From ddb3c15d4b381ef244aa56cc1a4c4f407faa1479 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 26 Dec 2015 17:03:42 +0100 Subject: [PATCH 001/110] some gcc5 compil fixes --- src/driver/record.cpp | 6 +++--- src/gui/components/cc_frm.cpp | 2 +- src/nhttpd/tuxboxapi/controlapi.cpp | 2 +- src/nhttpd/tuxboxapi/neutrinoyparser.cpp | 4 ++-- src/system/helpers.cpp | 3 ++- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/driver/record.cpp b/src/driver/record.cpp index a9f42398a..7aedd725d 100644 --- a/src/driver/record.cpp +++ b/src/driver/record.cpp @@ -731,7 +731,7 @@ void CRecordInstance::MakeExtFileName(CZapitChannel * channel, std::string &File std::string channel_name = channel->getName(); if (!(channel_name.empty())) { - snprintf(buf, sizeof(buf), UTF8_TO_FILESYSTEM_ENCODING(channel_name.c_str())); + snprintf(buf, sizeof(buf),"%s", UTF8_TO_FILESYSTEM_ENCODING(channel_name.c_str())); ZapitTools::replace_char(buf); StringReplace(FilenameTemplate,"%C",buf); } @@ -741,7 +741,7 @@ void CRecordInstance::MakeExtFileName(CZapitChannel * channel, std::string &File CShortEPGData epgdata; if(CEitManager::getInstance()->getEPGidShort(epgid, &epgdata)) { if (!(epgdata.title.empty())) { - snprintf(buf, sizeof(buf), epgdata.title.c_str()); + snprintf(buf, sizeof(buf),"%s", epgdata.title.c_str()); ZapitTools::replace_char(buf); StringReplace(FilenameTemplate,"%T",buf); } @@ -749,7 +749,7 @@ void CRecordInstance::MakeExtFileName(CZapitChannel * channel, std::string &File StringReplace(FilenameTemplate,"%T","no_title"); if (!(epgdata.info1.empty())) { - snprintf(buf, sizeof(buf), epgdata.info1.c_str()); + snprintf(buf, sizeof(buf),"%s", epgdata.info1.c_str()); ZapitTools::replace_char(buf); StringReplace(FilenameTemplate,"%I",buf); } diff --git a/src/gui/components/cc_frm.cpp b/src/gui/components/cc_frm.cpp index fb4b3c779..3b4e6c3fe 100644 --- a/src/gui/components/cc_frm.cpp +++ b/src/gui/components/cc_frm.cpp @@ -251,7 +251,7 @@ int CComponentsForm::genIndex() CComponentsItem* CComponentsForm::getCCItem(const uint& cc_item_id) { if (cc_item_id >= size()){ - dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] Error: parameter cc_item_id = %u, out of range (size = %u)...\n", __func__, __LINE__, cc_item_id, size()); + dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] Error: parameter cc_item_id = %u, out of range (size = %" PRIx64")...\n", __func__, __LINE__, cc_item_id, size()); return NULL; } diff --git a/src/nhttpd/tuxboxapi/controlapi.cpp b/src/nhttpd/tuxboxapi/controlapi.cpp index 586c51b39..90a6d2735 100644 --- a/src/nhttpd/tuxboxapi/controlapi.cpp +++ b/src/nhttpd/tuxboxapi/controlapi.cpp @@ -857,7 +857,7 @@ void CControlAPI::LogolistCGI(CyhookHandler *hh) if (pos < v.size()) continue; v.push_back(channel->getChannelID()); - result += string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS";%s;"PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS"", channel->getChannelID(), channel->getName().c_str(), (channel->getChannelID() & 0xFFFFFFFFFFFFULL)); + result += string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS";%s;" PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS"", channel->getChannelID(), channel->getName().c_str(), (channel->getChannelID() & 0xFFFFFFFFFFFFULL)); if (hh->ParamList["1"].compare("files") == 0) { diff --git a/src/nhttpd/tuxboxapi/neutrinoyparser.cpp b/src/nhttpd/tuxboxapi/neutrinoyparser.cpp index c0522547c..c38776db3 100644 --- a/src/nhttpd/tuxboxapi/neutrinoyparser.cpp +++ b/src/nhttpd/tuxboxapi/neutrinoyparser.cpp @@ -383,7 +383,7 @@ std::string CNeutrinoYParser::func_get_bouquets_with_epg(CyhookHandler *hh, std: yresult += string_printf( "" - "" + "" "%s" "" "" @@ -531,7 +531,7 @@ std::string CNeutrinoYParser::func_get_logo_name(CyhookHandler *hh, std::string { if (hh->WebserverConfigList["Tuxbox.DisplayLogos"] == "true") { t_channel_id cid; - if (1 == sscanf(channelId.c_str(), "%llx", &cid)) + if (1 == sscanf(channelId.c_str(), "%" PRIx64, &cid)) return NeutrinoAPI->getLogoFile(hh->WebserverConfigList["Tuxbox.LogosURL"], cid); } return ""; diff --git a/src/system/helpers.cpp b/src/system/helpers.cpp index a66f53e8c..8ff3fbd4a 100644 --- a/src/system/helpers.cpp +++ b/src/system/helpers.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -282,7 +283,7 @@ int check_dir(const char * dir, bool allow_tmp) ret = 0; // ok } if(ret == -1) - printf("Wrong Filessystem Type: 0x%x\n",s.f_type); + printf("Wrong Filessystem Type: 0x%" PRIx64"\n",s.f_type); } return ret; } From 93e302211eff82632a16494b4a0fe89bf7d46ea9 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 26 Dec 2015 17:36:58 +0100 Subject: [PATCH 002/110] src/gui/imageinfo.cpp fix heap-use-after-free --- src/gui/imageinfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/imageinfo.cpp b/src/gui/imageinfo.cpp index 4bee68b10..919ec0432 100644 --- a/src/gui/imageinfo.cpp +++ b/src/gui/imageinfo.cpp @@ -249,8 +249,8 @@ void CImageInfo::InitInfoData() #ifdef IMAGE_VERSION version_string = IMAGE_VERSION; #else - const char * _version = config.getString("version", "U000000000000000").c_str(); - static CFlashVersionInfo versionInfo(_version); + std::string _version = config.getString("version", "U000000000000000").c_str(); + static CFlashVersionInfo versionInfo(_version.c_str()); version_string = versionInfo.getReleaseCycle(); version_string += " "; From fba05d0e80f5ea17e49105f7bcd535a15efab4ae Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 26 Dec 2015 18:37:26 +0100 Subject: [PATCH 003/110] src/gui/streaminfo2.cpp change sprintf to snprintf (fix possible segfault) --- src/gui/streaminfo2.cpp | 74 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/gui/streaminfo2.cpp b/src/gui/streaminfo2.cpp index 150aa81f3..78a0ce81a 100644 --- a/src/gui/streaminfo2.cpp +++ b/src/gui/streaminfo2.cpp @@ -181,7 +181,7 @@ int CStreamInfo2::doSignalStrengthLoop () rate.min_short_average = minb = bit_s; char currate[150]; - sprintf(tmp_str, "%s:",g_Locale->getText(LOCALE_STREAMINFO_BITRATE)); + snprintf(tmp_str,sizeof(tmp_str), "%s:",g_Locale->getText(LOCALE_STREAMINFO_BITRATE)); g_Font[font_info]->RenderString(dx1 , average_bitrate_pos, offset+10, tmp_str, COL_INFOBAR_TEXT); sprintf(currate, "%5llu.%02llu", rate.short_average / 1000ULL, rate.short_average % 1000ULL); @@ -189,7 +189,7 @@ int CStreamInfo2::doSignalStrengthLoop () g_Font[font_info]->RenderString (dx1 + average_bitrate_offset , average_bitrate_pos, sw - 10, currate, COL_INFOBAR_TEXT); - sprintf(tmp_str, "(%s)",g_Locale->getText(LOCALE_STREAMINFO_AVERAGE_BITRATE)); + snprintf(tmp_str,sizeof(tmp_str), "(%s)",g_Locale->getText(LOCALE_STREAMINFO_AVERAGE_BITRATE)); g_Font[font_info]->RenderString (dx1 + average_bitrate_offset + sw , average_bitrate_pos, sw *2, tmp_str, COL_INFOBAR_TEXT); } @@ -519,30 +519,30 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) //Video RESOLUTION ypos += iheight; - sprintf (buf, "%s:",g_Locale->getText (LOCALE_STREAMINFO_RESOLUTION)); + snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_STREAMINFO_RESOLUTION)); g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); - sprintf (buf, "%dx%d", xres, yres); + snprintf(buf, sizeof(buf), "%dx%d", xres, yres); g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); //audio rate ypos += iheight; - sprintf (buf, "%s:",g_Locale->getText (LOCALE_STREAMINFO_ARATIO)); + snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_STREAMINFO_ARATIO)); g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); switch (aspectRatio) { case 0: - sprintf (buf, "N/A"); + snprintf(buf, sizeof(buf), "N/A"); break; case 1: - sprintf (buf, "4:3"); + snprintf(buf, sizeof(buf), "4:3"); break; case 2: - sprintf (buf, "14:9"); + snprintf(buf, sizeof(buf), "14:9"); break; case 3: - sprintf (buf, "16:9"); + snprintf(buf, sizeof(buf), "16:9"); break; case 4: - sprintf (buf, "20:9"); + snprintf(buf, sizeof(buf), "20:9"); break; default: strncpy (buf, g_Locale->getText (LOCALE_STREAMINFO_ARATIO_UNKNOWN), sizeof (buf)-1); @@ -551,7 +551,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) //Video FRAMERATE ypos += iheight; - sprintf (buf, "%s:", g_Locale->getText (LOCALE_STREAMINFO_FRAMERATE)); + snprintf(buf, sizeof(buf), "%s:", g_Locale->getText (LOCALE_STREAMINFO_FRAMERATE)); g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); switch (framerate) { case 0: @@ -590,17 +590,17 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) int type, layer, freq, mode, lbitrate; audioDecoder->getAudioInfo(type, layer, freq, lbitrate, mode); - sprintf (buf, "%s:", g_Locale->getText (LOCALE_STREAMINFO_AUDIOTYPE)); + snprintf(buf, sizeof(buf), "%s:", g_Locale->getText (LOCALE_STREAMINFO_AUDIOTYPE)); g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); if(type == AUDIO_FMT_MPEG) { const int max_mode = 4; const char *mpegmodes[max_mode] = { "stereo", "joint_st", "dual_ch", "single_ch" }; - sprintf (buf, "MPEG %s (%d)", (mode > max_mode) ?"unk":mpegmodes[mode], freq); + snprintf(buf, sizeof(buf), "MPEG %s (%d)", (mode > max_mode) ?"unk":mpegmodes[mode], freq); } else if (type == AUDIO_FMT_DOLBY_DIGITAL || type == AUDIO_FMT_DD_PLUS) { const int max_mode = 8; const char *ddmodes[max_mode] = { "CH1/CH2", "C", "L/R", "L/C/R", "L/R/S", "L/C/R/S", "L/R/SL/SR", "L/C/R/SL/SR" }; - sprintf (buf, "%s %s (%d)", + snprintf(buf, sizeof(buf), "%s %s (%d)", (type == AUDIO_FMT_DOLBY_DIGITAL) ? "DD" : "DD+", (mode > max_mode) ?"unk": ddmodes[mode], freq); @@ -618,11 +618,11 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) "L/R/SL/SR", "Dual-Mono" }; - sprintf (buf, "%s %s (%d)", + snprintf(buf, sizeof(buf), "%s %s (%d)", (type == AUDIO_FMT_AAC) ? "AAC" : "AAC+", (mode > max_mode) ?"unk":aacmodes[mode], freq); } else { - sprintf (buf, "%s (%d)", g_Locale->getText(LOCALE_STREAMINFO_AUDIOTYPE_UNKNOWN), freq); + snprintf(buf, sizeof(buf), "%s (%d)", g_Locale->getText(LOCALE_STREAMINFO_AUDIOTYPE_UNKNOWN), freq); } g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); @@ -630,14 +630,14 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) //channel ypos += iheight; if (CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_webtv) { - sprintf (buf, "%s:",g_Locale->getText (LOCALE_TIMERLIST_CHANNEL));//swiped locale + snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_TIMERLIST_CHANNEL));//swiped locale g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); - sprintf(buf, "%s", channel->getName().c_str()); + snprintf(buf, sizeof(buf), "%s", channel->getName().c_str()); g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); } else { - sprintf (buf, "%s:",g_Locale->getText (LOCALE_MOVIEBROWSER_INFO_FILE));//swiped locale + snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_MOVIEBROWSER_INFO_FILE));//swiped locale g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); - sprintf(buf, "%s", mp->GetFile().c_str()); + snprintf(buf, sizeof(buf), "%s", mp->GetFile().c_str()); g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); } @@ -649,24 +649,24 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) //satellite ypos += iheight; if (CFrontend::isSat(t.feparams.delsys)) - sprintf (buf, "%s:",g_Locale->getText (LOCALE_SATSETUP_SATELLITE));//swiped locale + snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_SATSETUP_SATELLITE));//swiped locale else if (CFrontend::isCable(t.feparams.delsys)) - sprintf (buf, "%s:",g_Locale->getText (LOCALE_CHANNELLIST_PROVS)); + snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_CHANNELLIST_PROVS)); else if (CFrontend::isTerr(t.feparams.delsys)) - snprintf (buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_TERRESTRIALSETUP_AREA)); + snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_TERRESTRIALSETUP_AREA)); g_Font[font_info]->RenderString(xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); - sprintf (buf, "%s", IS_WEBTV(channel->getChannelID()) ? g_Locale->getText(LOCALE_WEBTV_HEAD) : + snprintf(buf, sizeof(buf), "%s", IS_WEBTV(channel->getChannelID()) ? g_Locale->getText(LOCALE_WEBTV_HEAD) : CServiceManager::getInstance()->GetSatelliteName(channel->getSatellitePosition()).c_str()); g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); //channel ypos += iheight; - sprintf (buf, "%s:",g_Locale->getText (LOCALE_TIMERLIST_CHANNEL));//swiped locale + snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_TIMERLIST_CHANNEL));//swiped locale g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); // process additional RealName if UserName exists >> uname.empty() ? realname : uname + realname - sprintf(buf, "%s", (channel->getName()==channel->getRealname()) ? channel->getRealname().c_str():(channel->getName()+" << "+channel->getRealname()).c_str()); + snprintf(buf, sizeof(buf), "%s", (channel->getName()==channel->getRealname()) ? channel->getRealname().c_str():(channel->getName()+" << "+channel->getRealname()).c_str()); g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); //tsfrequenz @@ -676,7 +676,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) if (CFrontend::isSat(t.feparams.delsys) && t.feparams.delsys == DVB_S) scaling = 15000; - sprintf (buf, "%s",g_Locale->getText (LOCALE_SCANTS_FREQDATA)); + snprintf(buf, sizeof(buf), "%s",g_Locale->getText (LOCALE_SCANTS_FREQDATA)); g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); g_Font[font_info]->RenderString(xpos+spaceoffset, ypos, box_width, t.description().c_str(), COL_INFOBAR_TEXT); @@ -685,35 +685,35 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) spaceoffset = 7 * fontW; //onid ypos+= sheight; - sprintf(buf, "0x%04X (%i)", channel->getOriginalNetworkId(), channel->getOriginalNetworkId()); + snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getOriginalNetworkId(), channel->getOriginalNetworkId()); g_Font[font_small]->RenderString(xpos, ypos, box_width, "ONid:" , COL_INFOBAR_TEXT); g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); //sid ypos+= sheight; - sprintf(buf, "0x%04X (%i)", channel->getServiceId(), channel->getServiceId()); + snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getServiceId(), channel->getServiceId()); g_Font[font_small]->RenderString(xpos, ypos, box_width, "Sid:" , COL_INFOBAR_TEXT); g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); //tsid ypos+= sheight; - sprintf(buf, "0x%04X (%i)", channel->getTransportStreamId(), channel->getTransportStreamId()); + snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getTransportStreamId(), channel->getTransportStreamId()); g_Font[font_small]->RenderString(xpos, ypos, box_width, "TSid:" , COL_INFOBAR_TEXT); g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); //pmtpid ypos+= sheight; pmt_version = channel->getPmtVersion(); - sprintf(buf, "0x%04X (%i) [0x%02X]", channel->getPmtPid(), channel->getPmtPid(), pmt_version); + snprintf(buf, sizeof(buf), "0x%04X (%i) [0x%02X]", channel->getPmtPid(), channel->getPmtPid(), pmt_version); g_Font[font_small]->RenderString(xpos, ypos, box_width, "PMTpid:", COL_INFOBAR_TEXT); g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); //vpid ypos+= sheight; if ( g_RemoteControl->current_PIDs.PIDs.vpid > 0 ){ - sprintf(buf, "0x%04X (%i)", g_RemoteControl->current_PIDs.PIDs.vpid, g_RemoteControl->current_PIDs.PIDs.vpid ); + snprintf(buf, sizeof(buf), "0x%04X (%i)", g_RemoteControl->current_PIDs.PIDs.vpid, g_RemoteControl->current_PIDs.PIDs.vpid ); } else { - sprintf(buf, "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); + snprintf(buf, sizeof(buf), "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); } g_Font[font_small]->RenderString(xpos, ypos, box_width, "Vpid:" , COL_INFOBAR_TEXT); g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); @@ -722,12 +722,12 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) ypos+= sheight; g_Font[font_small]->RenderString(xpos, ypos, box_width, "Apid(s):" , COL_INFOBAR_TEXT); if (g_RemoteControl->current_PIDs.APIDs.empty()){ - sprintf(buf, "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); + snprintf(buf, sizeof(buf), "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); } else { unsigned int sw=spaceoffset; for (unsigned int li= 0; (licurrent_PIDs.APIDs.size()) && (li<16); li++) { - sprintf(buf, "0x%04X (%i)", g_RemoteControl->current_PIDs.APIDs[li].pid, g_RemoteControl->current_PIDs.APIDs[li].pid ); + snprintf(buf, sizeof(buf), "0x%04X (%i)", g_RemoteControl->current_PIDs.APIDs[li].pid, g_RemoteControl->current_PIDs.APIDs[li].pid ); if (li == g_RemoteControl->current_PIDs.PIDs.selected_apid){ g_Font[font_small]->RenderString(xpos+sw, ypos, box_width, buf, COL_MENUHEAD_TEXT); } @@ -745,9 +745,9 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) //vtxtpid ypos += sheight; if ( g_RemoteControl->current_PIDs.PIDs.vtxtpid == 0 ) - sprintf(buf, "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); + snprintf(buf, sizeof(buf), "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); else - sprintf(buf, "0x%04X (%i)", g_RemoteControl->current_PIDs.PIDs.vtxtpid, g_RemoteControl->current_PIDs.PIDs.vtxtpid ); + snprintf(buf, sizeof(buf), "0x%04X (%i)", g_RemoteControl->current_PIDs.PIDs.vtxtpid, g_RemoteControl->current_PIDs.PIDs.vtxtpid ); g_Font[font_small]->RenderString(xpos, ypos, box_width, "VTXTpid:" , COL_INFOBAR_TEXT); g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); if(box_h == 0) From c565223bc752e5ba6bcff6a20d10170f87d7f1c8 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 26 Dec 2015 19:13:17 +0100 Subject: [PATCH 004/110] src/gui/streaminfo2.cpp fix box width --- src/gui/streaminfo2.cpp | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/gui/streaminfo2.cpp b/src/gui/streaminfo2.cpp index 78a0ce81a..f166f6e50 100644 --- a/src/gui/streaminfo2.cpp +++ b/src/gui/streaminfo2.cpp @@ -485,7 +485,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) // paint labels int spaceoffset = 0,i = 0; int ypos1 = ypos; - int box_width = width*2/3 - 10; + int box_width = width-width/3-10; yypos = ypos; if(box_h > 0) @@ -509,6 +509,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) spaceoffset += g_Font[font_info]->getRenderWidth(" "); average_bitrate_offset = spaceoffset; + int box_width2 = box_width-(spaceoffset+xpos); if((channel->getVideoPid() || IS_WEBTV(channel->getChannelID())) && !(videoDecoder->getBlank())){ videoDecoder->getPictureInfo(xres, yres, framerate); @@ -522,7 +523,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_STREAMINFO_RESOLUTION)); g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); snprintf(buf, sizeof(buf), "%dx%d", xres, yres); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //audio rate ypos += iheight; @@ -547,7 +548,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) default: strncpy (buf, g_Locale->getText (LOCALE_STREAMINFO_ARATIO_UNKNOWN), sizeof (buf)-1); } - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //Video FRAMERATE ypos += iheight; @@ -582,7 +583,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) strncpy (buf, g_Locale->getText (LOCALE_STREAMINFO_FRAMERATE_UNKNOWN), sizeof (buf)-1); break; } - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); // place for average bitrate average_bitrate_pos = ypos += iheight; //AUDIOTYPE @@ -624,7 +625,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) } else { snprintf(buf, sizeof(buf), "%s (%d)", g_Locale->getText(LOCALE_STREAMINFO_AUDIOTYPE_UNKNOWN), freq); } - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); if (mp) { //channel @@ -633,12 +634,12 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_TIMERLIST_CHANNEL));//swiped locale g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); snprintf(buf, sizeof(buf), "%s", channel->getName().c_str()); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); } else { snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_MOVIEBROWSER_INFO_FILE));//swiped locale g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); snprintf(buf, sizeof(buf), "%s", mp->GetFile().c_str()); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); } scaling = 27000; @@ -659,7 +660,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) snprintf(buf, sizeof(buf), "%s", IS_WEBTV(channel->getChannelID()) ? g_Locale->getText(LOCALE_WEBTV_HEAD) : CServiceManager::getInstance()->GetSatelliteName(channel->getSatellitePosition()).c_str()); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //channel ypos += iheight; @@ -667,7 +668,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); // process additional RealName if UserName exists >> uname.empty() ? realname : uname + realname snprintf(buf, sizeof(buf), "%s", (channel->getName()==channel->getRealname()) ? channel->getRealname().c_str():(channel->getName()+" << "+channel->getRealname()).c_str()); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //tsfrequenz ypos += iheight; @@ -678,35 +679,36 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) snprintf(buf, sizeof(buf), "%s",g_Locale->getText (LOCALE_SCANTS_FREQDATA)); g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); - g_Font[font_info]->RenderString(xpos+spaceoffset, ypos, box_width, t.description().c_str(), COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString(xpos+spaceoffset, ypos, box_width2, t.description().c_str(), COL_INFOBAR_TEXT); // paint labels int fontW = g_Font[font_small]->getWidth(); spaceoffset = 7 * fontW; + box_width2 = box_width-(spaceoffset+xpos); //onid ypos+= sheight; snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getOriginalNetworkId(), channel->getOriginalNetworkId()); g_Font[font_small]->RenderString(xpos, ypos, box_width, "ONid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //sid ypos+= sheight; snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getServiceId(), channel->getServiceId()); g_Font[font_small]->RenderString(xpos, ypos, box_width, "Sid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //tsid ypos+= sheight; snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getTransportStreamId(), channel->getTransportStreamId()); g_Font[font_small]->RenderString(xpos, ypos, box_width, "TSid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //pmtpid ypos+= sheight; pmt_version = channel->getPmtVersion(); snprintf(buf, sizeof(buf), "0x%04X (%i) [0x%02X]", channel->getPmtPid(), channel->getPmtPid(), pmt_version); g_Font[font_small]->RenderString(xpos, ypos, box_width, "PMTpid:", COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //vpid ypos+= sheight; @@ -716,7 +718,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) snprintf(buf, sizeof(buf), "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); } g_Font[font_small]->RenderString(xpos, ypos, box_width, "Vpid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); //apid ypos+= sheight; @@ -729,10 +731,10 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) { snprintf(buf, sizeof(buf), "0x%04X (%i)", g_RemoteControl->current_PIDs.APIDs[li].pid, g_RemoteControl->current_PIDs.APIDs[li].pid ); if (li == g_RemoteControl->current_PIDs.PIDs.selected_apid){ - g_Font[font_small]->RenderString(xpos+sw, ypos, box_width, buf, COL_MENUHEAD_TEXT); + g_Font[font_small]->RenderString(xpos+sw, ypos, box_width2, buf, COL_MENUHEAD_TEXT); } else{ - g_Font[font_small]->RenderString(xpos+sw, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos+sw, ypos, box_width2, buf, COL_INFOBAR_TEXT); } sw = g_Font[font_small]->getRenderWidth(buf)+sw+10; if (((li+1)%4 == 0) &&(g_RemoteControl->current_PIDs.APIDs.size()-1 > li)){ // if we have lots of apids, put "intermediate" line with pids @@ -749,7 +751,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) else snprintf(buf, sizeof(buf), "0x%04X (%i)", g_RemoteControl->current_PIDs.PIDs.vtxtpid, g_RemoteControl->current_PIDs.PIDs.vtxtpid ); g_Font[font_small]->RenderString(xpos, ypos, box_width, "VTXTpid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); if(box_h == 0) box_h = ypos - ypos1; yypos = ypos; From 322b58a598e9183bbe842f63dabec99c129d8848 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sun, 27 Dec 2015 13:58:32 +0100 Subject: [PATCH 005/110] fix compil fix change 64 to 32 --- src/gui/components/cc_frm.cpp | 2 +- src/system/helpers.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/components/cc_frm.cpp b/src/gui/components/cc_frm.cpp index 3b4e6c3fe..69fa66b3c 100644 --- a/src/gui/components/cc_frm.cpp +++ b/src/gui/components/cc_frm.cpp @@ -251,7 +251,7 @@ int CComponentsForm::genIndex() CComponentsItem* CComponentsForm::getCCItem(const uint& cc_item_id) { if (cc_item_id >= size()){ - dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] Error: parameter cc_item_id = %u, out of range (size = %" PRIx64")...\n", __func__, __LINE__, cc_item_id, size()); + dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] Error: parameter cc_item_id = %u, out of range (size = %" PRIx32")...\n", __func__, __LINE__, cc_item_id, size()); return NULL; } diff --git a/src/system/helpers.cpp b/src/system/helpers.cpp index 8ff3fbd4a..bae705934 100644 --- a/src/system/helpers.cpp +++ b/src/system/helpers.cpp @@ -283,7 +283,7 @@ int check_dir(const char * dir, bool allow_tmp) ret = 0; // ok } if(ret == -1) - printf("Wrong Filessystem Type: 0x%" PRIx64"\n",s.f_type); + printf("Wrong Filessystem Type: 0x%" PRIx32"\n",s.f_type); } return ret; } From a886d49565fbe2996a14f1a6a90c5a076a719209 Mon Sep 17 00:00:00 2001 From: max10 Date: Sun, 27 Dec 2015 10:29:08 +0100 Subject: [PATCH 006/110] fix src/system/helpers.cpp: PRIx64 --- src/system/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/Makefile.am b/src/system/Makefile.am index ac7c5da18..37c20cb21 100644 --- a/src/system/Makefile.am +++ b/src/system/Makefile.am @@ -2,7 +2,7 @@ if BOXMODEL_APOLLO SUBDIRS = mtdutils endif -AM_CXXFLAGS = -fno-rtti -fno-exceptions +AM_CXXFLAGS = -fno-rtti -fno-exceptions -D__STDC_FORMAT_MACROS AM_CPPFLAGS = \ -I$(top_builddir) \ From a2171dad4a0032f7be41689ee580f79e08d296bf Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 17:13:43 +0100 Subject: [PATCH 007/110] CTextBox: add/modify methodes for screen handlings - split hasChanged() into hasChangedPos(), hasChangedDim() - add return value bool to enableBackgroundPaint(), enableSaveScreen() - add clearScreenBuffer(), for unified usage in destructor and functions - add OnAfterRefresh() as a signal/slot handler, this allows to use external methodes as callbacks after painted text --- src/gui/widget/textbox.cpp | 66 ++++++++++++++++++++++++++++---------- src/gui/widget/textbox.h | 13 +++++--- 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/gui/widget/textbox.cpp b/src/gui/widget/textbox.cpp index f1bb3ab84..70d642bf8 100644 --- a/src/gui/widget/textbox.cpp +++ b/src/gui/widget/textbox.cpp @@ -135,7 +135,7 @@ CTextBox::~CTextBox() //TRACE("[CTextBox] del\r\n"); m_cLineArray.clear(); //hide(); - delete[] m_bgpixbuf; + clearScreenBuffer(); } void CTextBox::initVar(void) @@ -515,10 +515,8 @@ void CTextBox::refreshScroll(void) //first init is done in initVar() and reinit done in reInitToCompareVar() bool CTextBox::hasChanged(int* x, int* y, int* dx, int* dy) { - if ( m_old_x != *x - || m_old_y != *y - || m_old_dx != *dx - || m_old_dy != *dy + if ( hasChangedPos(x, y) + || hasChangedDim(dx, dy) || m_old_textBackgroundColor != m_textBackgroundColor || m_old_textColor != m_textColor || m_old_nBgRadius != m_nBgRadius @@ -528,6 +526,17 @@ bool CTextBox::hasChanged(int* x, int* y, int* dx, int* dy) } return false; } + +bool CTextBox::hasChangedPos(int* x, int* y) +{ + return (m_old_x != *x || m_old_y != *y); +} + +bool CTextBox::hasChangedDim(int* dx, int* dy) +{ + return (m_old_dx != *dx || m_old_dy != *dy); +} + void CTextBox::reInitToCompareVar(int* x, int* y, int* dx, int* dy) { m_old_x = *x; @@ -560,13 +569,14 @@ void CTextBox::refreshText(void) //find changes bool has_changed = hasChanged(&ax, &ay, &dx, &dy); - //destroy pixel buffer on changed property values - if (has_changed){ - if (m_bgpixbuf){ - //TRACE("[CTextBox] %s destroy ol pixel buffer, has changes %d\r\n", __FUNCTION__, __LINE__); - delete[] m_bgpixbuf; - m_bgpixbuf = NULL; - } + //clean up possible screen on any changes + if (has_changed && m_bgpixbuf){ + /*TODO/FIXME: in some cases could be required, that we must restore old saved screen. eg. if a text without bg was painted + * and another text should be painted as next on the same position like current text, but new text will be overpaint and is + * not visible. It's currently solvable only with appropriate order of text items + */ + frameBuffer->RestoreScreen(m_old_x, m_old_y, m_old_dx, m_old_dy, m_bgpixbuf); + clearScreenBuffer(); } //detect corrupt position values @@ -589,11 +599,7 @@ void CTextBox::refreshText(void) //Paint Text Background bool allow_paint_bg = (m_old_cText != m_cText || has_changed || m_has_scrolled); if (m_nPaintBackground){ - if (m_bgpixbuf){ - //TRACE("[CTextBox] %s destroy bg %d\r\n", __FUNCTION__, __LINE__); - delete[] m_bgpixbuf; - m_bgpixbuf = NULL; - } + clearScreenBuffer(); if (allow_paint_bg){ //TRACE("[CTextBox] %s paint bg %d\r\n", __FUNCTION__, __LINE__); frameBuffer->paintBoxRel(ax, ay, dx, dy, m_textBackgroundColor, m_nBgRadius, m_nBgRadiusType); @@ -713,6 +719,7 @@ void CTextBox::refresh(void) //Paint text refreshScroll(); refreshText(); + OnAfterRefresh(); } @@ -772,3 +779,28 @@ void CTextBox::hide (void) frameBuffer = NULL; } + +bool CTextBox::clearScreenBuffer() +{ + if(m_bgpixbuf){ + //TRACE("[CTextBox] %s destroy bg %d\r\n", __FUNCTION__, __LINE__); + delete[] m_bgpixbuf; + m_bgpixbuf = NULL; + return true; + } + return false; +} + +bool CTextBox::enableSaveScreen(bool mode) +{ + if (m_SaveScreen == mode) + return false; + + if (!m_SaveScreen || m_SaveScreen != mode) + clearScreenBuffer(); + + m_SaveScreen = mode; + + return true; +} + diff --git a/src/gui/widget/textbox.h b/src/gui/widget/textbox.h index 7ba687443..860e2cd7b 100644 --- a/src/gui/widget/textbox.h +++ b/src/gui/widget/textbox.h @@ -62,7 +62,7 @@ #include #include #include - +#include #define TRACE printf #define TRACE_1 printf @@ -81,7 +81,7 @@ class CBox int iHeight; }; -class CTextBox +class CTextBox : public sigc::trackable { public: /* Variables */ @@ -110,6 +110,8 @@ class CTextBox void reSizeMainFrameHeight(int maxTextHeight); bool hasChanged(int* x, int* y, int* dx, int* dy); + bool hasChangedPos(int* x, int* y); + bool hasChangedDim(int* dx, int* dy); void reInitToCompareVar(int* x, int* y, int* dx, int* dy); /* Variables */ @@ -179,8 +181,9 @@ class CTextBox void refresh(void); void scrollPageDown(const int pages); void scrollPageUp(const int pages); - void enableBackgroundPaint(bool mode = true){m_nPaintBackground = mode;}; - void enableSaveScreen(bool mode = true){m_SaveScreen = mode;}; + void enableBackgroundPaint(bool mode = true){m_nPaintBackground = mode;} + //enable screen saving behind chars, is required for transparent text paint, returns true if mode was changed + bool enableSaveScreen(bool mode = true); bool setText(const std::string* newText, int max_width = 0, bool force_repaint = true); void setTextColor(fb_pixel_t color_text){ m_textColor = color_text;}; void setBackGroundRadius(const int radius, const int type = CORNER_ALL){m_nBgRadius = radius; m_nBgRadiusType = type;}; @@ -207,6 +210,8 @@ class CTextBox inline int getTextMode() {return m_nMode;}; void paint (void); void hide (void); + bool clearScreenBuffer(); + sigc::signal OnAfterRefresh; }; #endif // !defined(AFX_TEXTBOX_H__208DED01_ABEC_491C_A632_5B21057DC5D8__INCLUDED_) From 0146511f3882c71fc529d33aaea514c307214a2d Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 18:08:23 +0100 Subject: [PATCH 008/110] components: rework classes - outsourced some classes cc_item.cpp/h, cc_draw.cpp/h - added extra methodes for simple use of some basic components extra.cpp/h - rework clock handling: use timer class, reworked members for enable/disable clock with external timer events, tryed to fix some display issues related with infoclock and time osd clock in moviebrowser, channellist, menuus - reworked hide/kill handling, removed parameter for hide(), try to use cached backgrounds for other constallations, paint cache, image cache (all beta) - reworked shadow/frame handling, add shadow modes for left/right arrangement, TODO: repaint for existant instances required - reworked color gradient assignment (beta) ... Note: I had a data crash in my local git tree and i tryed to restore my historie, but most was lost. Therefore here the commit is large --- src/driver/colorgradient.cpp | 10 +- src/driver/framebuffer.cpp | 18 +- src/driver/framebuffer.h | 5 +- src/gui/audiomute.cpp | 26 +- src/gui/bouquetlist.cpp | 5 +- src/gui/channellist.cpp | 144 +++-- src/gui/channellist.h | 6 +- src/gui/components/Makefile.am | 2 + src/gui/components/cc.h | 10 +- src/gui/components/cc_base.cpp | 305 +-------- src/gui/components/cc_base.h | 349 +---------- src/gui/components/cc_detailsline.cpp | 63 +- src/gui/components/cc_draw.cpp | 692 +++++++++++++++++++++ src/gui/components/cc_draw.h | 309 +++++++++ src/gui/components/cc_extra.cpp | 123 ++++ src/gui/components/cc_extra.h | 276 ++++++++ src/gui/components/cc_frm.cpp | 82 ++- src/gui/components/cc_frm.h | 21 +- src/gui/components/cc_frm_button.cpp | 30 +- src/gui/components/cc_frm_button.h | 45 +- src/gui/components/cc_frm_chain.cpp | 8 +- src/gui/components/cc_frm_chain.h | 4 +- src/gui/components/cc_frm_clock.cpp | 431 +++++++------ src/gui/components/cc_frm_clock.h | 134 ++-- src/gui/components/cc_frm_ext_text.cpp | 20 +- src/gui/components/cc_frm_ext_text.h | 16 +- src/gui/components/cc_frm_footer.cpp | 12 +- src/gui/components/cc_frm_footer.h | 4 +- src/gui/components/cc_frm_header.cpp | 220 +++++-- src/gui/components/cc_frm_header.h | 49 +- src/gui/components/cc_frm_icons.cpp | 8 +- src/gui/components/cc_frm_icons.h | 4 +- src/gui/components/cc_frm_scrollbar.cpp | 8 +- src/gui/components/cc_frm_scrollbar.h | 2 +- src/gui/components/cc_frm_signalbars.cpp | 17 +- src/gui/components/cc_frm_slider.cpp | 16 +- src/gui/components/cc_frm_slider.h | 2 +- src/gui/components/cc_frm_window.cpp | 22 +- src/gui/components/cc_frm_window.h | 10 +- src/gui/components/cc_item.cpp | 180 ++---- src/gui/components/cc_item.h | 129 ++++ src/gui/components/cc_item_infobox.cpp | 8 +- src/gui/components/cc_item_infobox.h | 7 +- src/gui/components/cc_item_picture.cpp | 89 ++- src/gui/components/cc_item_picture.h | 43 +- src/gui/components/cc_item_progressbar.cpp | 263 ++++---- src/gui/components/cc_item_progressbar.h | 21 +- src/gui/components/cc_item_shapes.cpp | 16 +- src/gui/components/cc_item_shapes.h | 5 +- src/gui/components/cc_item_text.cpp | 134 ++-- src/gui/components/cc_item_text.h | 83 ++- src/gui/components/cc_item_tvpic.cpp | 10 +- src/gui/components/cc_item_tvpic.h | 5 +- src/gui/components/cc_text_screen.h | 44 ++ src/gui/components/cc_timer.cpp | 43 +- src/gui/components/cc_timer.h | 2 +- src/gui/components/cc_types.h | 54 +- src/gui/infoclock.cpp | 91 +-- src/gui/infoclock.h | 16 +- src/gui/streaminfo2.cpp | 2 +- src/gui/test_menu.cpp | 24 +- src/gui/timeosd.cpp | 66 +- src/gui/timerlist.cpp | 4 +- src/gui/volumebar.cpp | 23 +- src/gui/volumebar.h | 9 +- src/gui/widget/progresswindow.cpp | 6 +- src/gui/widget/progresswindow.h | 2 +- src/system/debug.h | 2 +- 68 files changed, 3207 insertions(+), 1682 deletions(-) create mode 100644 src/gui/components/cc_draw.cpp create mode 100644 src/gui/components/cc_draw.h create mode 100644 src/gui/components/cc_extra.cpp create mode 100644 src/gui/components/cc_extra.h create mode 100644 src/gui/components/cc_item.h create mode 100644 src/gui/components/cc_text_screen.h diff --git a/src/driver/colorgradient.cpp b/src/driver/colorgradient.cpp index 50dacddd2..e9ed0e97e 100644 --- a/src/driver/colorgradient.cpp +++ b/src/driver/colorgradient.cpp @@ -185,11 +185,15 @@ fb_pixel_t* CColorGradient::gradientColorToColor(fb_pixel_t start_col,fb_pixel_t int start_box = 0; int end_box = bSize; - if (mode == gradientDark2Light) { - fb_pixel_t temp_col = start_col; + fb_pixel_t temp_col = end_col; + end_col = start_col; + start_col = temp_col; + + if (mode == gradientDark2Light){ + temp_col = start_col; start_col = end_col; end_col = temp_col; - } + } uint8_t start_tr = (uint8_t)((start_col & 0xFF000000) >> 24); uint8_t start_r = (uint8_t)((start_col & 0x00FF0000) >> 16); diff --git a/src/driver/framebuffer.cpp b/src/driver/framebuffer.cpp index dc58fccc9..66d4b8a21 100644 --- a/src/driver/framebuffer.cpp +++ b/src/driver/framebuffer.cpp @@ -658,6 +658,7 @@ void CFrameBuffer::paletteSet(struct fb_cmap *map) realcolor[i] = make16color(cmap.red[i], cmap.green[i], cmap.blue[i], cmap.transp[i], rl, ro, gl, go, bl, bo, tl, to); } + OnAfterSetPallette(); } void CFrameBuffer::paintHLineRelInternal2Buf(const int& x, const int& dx, const int& y, const int& box_dx, const fb_pixel_t& col, fb_pixel_t* buf) @@ -673,7 +674,7 @@ fb_pixel_t* CFrameBuffer::paintBoxRel2Buf(const int dx, const int dy, const fb_p if (!getActive()) return buf; if (dx == 0 || dy == 0) { - dprintf(DEBUG_INFO, "[%s - %d]: radius %d, dx %d dy %d\n", __func__, __LINE__, radius, dx, dy); + dprintf(DEBUG_INFO, "[CFrameBuffer] [%s - %d]: radius %d, dx %d dy %d\n", __func__, __LINE__, radius, dx, dy); return buf; } @@ -779,7 +780,7 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int return; if (dx == 0 || dy == 0) { - printf("[%s - %d]: radius %d, start x %d y %d end x %d y %d\n", __FUNCTION__, __LINE__, radius, x, y, x+dx, y+dy); + dprintf(DEBUG_NORMAL, "[CFrameBuffer] [%s - %d]: radius %d, start x %d y %d end x %d y %d\n", __FUNCTION__, __LINE__, radius, x, y, x+dx, y+dy); return; } @@ -826,11 +827,12 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int } if (dx-ofr-ofl < 1) { - if (dx-ofr-ofl == 0) - printf("[%s - %d]: radius %d, start x %d y %d end x %d y %d\n", __FUNCTION__, __LINE__, radius, x, y, x+dx-ofr-ofl, y+line); - else - printf("[%s - %04d]: Calculated width: %d\n (radius %d, dx %d, offsetLeft %d, offsetRight %d).\n Width can not be less than 0, abort.\n", - __FUNCTION__, __LINE__, dx-ofr-ofl, radius, dx, ofl, ofr); + if (dx-ofr-ofl == 0){ + dprintf(DEBUG_INFO, "[CFrameBuffer] [%s - %d]: radius %d, start x %d y %d end x %d y %d\n", __func__, __LINE__, radius, x, y, x+dx-ofr-ofl, y+line); + }else{ + dprintf(DEBUG_INFO, "[CFrameBuffer] [%s - %04d]: Calculated width: %d\n (radius %d, dx %d, offsetLeft %d, offsetRight %d).\n Width can not be less than 0, abort.\n", + __func__, __LINE__, dx-ofr-ofl, radius, dx, ofl, ofr); + } line++; continue; } @@ -2095,7 +2097,7 @@ bool CFrameBuffer::_checkFbArea(int _x, int _y, int _dx, int _dy, bool prev) // waitForIdle(); fb_no_check = true; if (prev) - CAudioMute::getInstance()->hide(true); + CAudioMute::getInstance()->hide(); else CAudioMute::getInstance()->paint(); fb_no_check = false; diff --git a/src/driver/framebuffer.h b/src/driver/framebuffer.h index 23f7c19a8..79c70450f 100644 --- a/src/driver/framebuffer.h +++ b/src/driver/framebuffer.h @@ -35,7 +35,7 @@ #include #include #include - +#include #define fb_pixel_t uint32_t typedef struct fb_var_screeninfo t_fb_var_screeninfo; @@ -69,7 +69,7 @@ typedef struct gradientData_t #define ConnectLineBox_Width 16 // px /** Ausfuehrung als Singleton */ -class CFrameBuffer +class CFrameBuffer : public sigc::trackable { private: @@ -323,6 +323,7 @@ class CFrameBuffer void fbNoCheck(bool noCheck) { fb_no_check = noCheck; } void doPaintMuteIcon(bool mode) { do_paint_mute_icon = mode; } void blit(void) {} + sigc::signal OnAfterSetPallette; }; #endif diff --git a/src/gui/audiomute.cpp b/src/gui/audiomute.cpp index a89fd8149..2b26a5d9f 100644 --- a/src/gui/audiomute.cpp +++ b/src/gui/audiomute.cpp @@ -5,7 +5,7 @@ audioMute - Neutrino-GUI Copyright (C) 2013 M. Liebmann (micha-bbg) CComponents implementation - Copyright (C) 2013 Thilo Graf + Copyright (C) 2013-2015 Thilo Graf License: GPL @@ -71,14 +71,21 @@ void CAudioMute::AudioMute(int newValue, bool isEvent) if (do_paint_mute_icon) { frameBuffer->fbNoCheck(true); - this->hide(true); + this->hide(); frameBuffer->fbNoCheck(false); } frameBuffer->setFbArea(CFrameBuffer::FB_PAINTAREA_MUTEICON1); y_old = y; } - if ((g_settings.mode_clock) && (doInit)) + + /* Infoclock should be blocked in all windows and clean the clock + * display with ClearDisplay() by itself before paint, + * so we don't do this here. + */ + if (!CInfoClock::getInstance()->isBlocked()){ CInfoClock::getInstance()->ClearDisplay(); + CInfoClock::getInstance()->paint();//avoids delay + } frameBuffer->fbNoCheck(true); if (newValue) { @@ -87,8 +94,13 @@ void CAudioMute::AudioMute(int newValue, bool isEvent) frameBuffer->setFbArea(CFrameBuffer::FB_PAINTAREA_MUTEICON1, x, y, width, height); } else { - if (do_paint_mute_icon) - this->hide(true); + if (!CInfoClock::getInstance()->isBlocked()){ + CInfoClock::getInstance()->ClearDisplay(); + this->kill(); + clearSavedScreen(); + CInfoClock::getInstance()->paint();//avoids delay + }else + this->hide(); frameBuffer->setFbArea(CFrameBuffer::FB_PAINTAREA_MUTEICON1); } frameBuffer->fbNoCheck(false); @@ -107,8 +119,8 @@ void CAudioMute::enableMuteIcon(bool enable) this->paint(); } else { - if (neutrino->isMuted()) - this->hide(true); + if (!neutrino->isMuted()) + this->kill(); frameBuffer->doPaintMuteIcon(false); do_paint_mute_icon = false; } diff --git a/src/gui/bouquetlist.cpp b/src/gui/bouquetlist.cpp index 331976f32..d46ec06f3 100644 --- a/src/gui/bouquetlist.cpp +++ b/src/gui/bouquetlist.cpp @@ -46,7 +46,7 @@ #include #include #include - +#include #include #include #include @@ -635,6 +635,7 @@ int CBouquetList::show(bool bShowChannelList) void CBouquetList::hide() { frameBuffer->paintBackgroundBoxRel(x,y, width,height+10); + CInfoClock::getInstance()->enableInfoClock(!CInfoClock::getInstance()->isBlocked()); } void CBouquetList::paintItem(int pos) @@ -702,6 +703,8 @@ void CBouquetList::paintHead() void CBouquetList::paint() { + //ensure stop info clock before paint this window + CInfoClock::getInstance()->disableInfoClock(); liststart = (selected/listmaxshow)*listmaxshow; int lastnum = liststart + listmaxshow; int bsize = Bouquets.empty() ? 1 : Bouquets.size(); diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index 5336a8ae4..bd39251b3 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -61,7 +61,7 @@ #include #include #include - +#include #include #include @@ -86,11 +86,11 @@ extern CBouquetList * TVfavList; extern CBouquetList * RADIOfavList; extern bool autoshift; - +static CComponentsPIP *cc_minitv = NULL; extern CBouquetManager *g_bouquetManager; - -static CComponentsFrmClock *headerClock = NULL; -static int headerClockWidth = 0; +extern int old_b_id; +static CComponentsChannelLogoScalable* CChannelLogo = NULL; +static CComponentsHeader *header = NULL; extern bool timeset; CChannelList::CChannelList(const char * const pName, bool phistoryMode, bool _vlist) @@ -130,24 +130,7 @@ CChannelList::CChannelList(const char * const pName, bool phistoryMode, bool _vl CChannelList::~CChannelList() { - if(dline){ - delete dline; - dline = NULL; - } - if (cc_minitv){ - delete cc_minitv; - cc_minitv = NULL; - } - if (headerClock) { - headerClock->clearSavedScreen(); - delete headerClock; - headerClock = NULL; - } - - if (CChannelLogo) { - delete CChannelLogo; - CChannelLogo = NULL; - } + ResetModules(); } void CChannelList::SetChannelList(ZapitChannelList* zlist) @@ -312,6 +295,18 @@ int CChannelList::doChannelMenu(void) CMenuWidget* menu = new CMenuWidget(LOCALE_CHANNELLIST_EDIT, NEUTRINO_ICON_SETTINGS); menu->enableFade(false); menu->enableSaveScreen(true); + + //ensure stop info clock before paint context menu + CInfoClock::getInstance()->block(); + + //ensure stop header clock before paint context menu + if (g_settings.menu_pos == CMenuWidget::MENU_POS_TOP_RIGHT){ + //using native callback to ensure stop header clock before paint this menu window + menu->OnBeforePaint.connect(sigc::mem_fun(header->getClockObject(), &CComponentsFrmClock::block)); + //... and start header clock after hide menu window + menu->OnAfterHide.connect(sigc::mem_fun(header->getClockObject(), &CComponentsFrmClock::unblock)); + } + CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select); bool empty = (*chanlist).empty(); @@ -420,7 +415,7 @@ int CChannelList::doChannelMenu(void) { previous_channellist_additional = g_settings.channellist_additional; COsdSetup osd_setup; - osd_setup.showContextChanlistMenu(); + osd_setup.showContextChanlistMenu(this); //FIXME check font/options changed ? hide(); calcSize(); @@ -601,7 +596,7 @@ int CChannelList::show() COSDFader fader(g_settings.theme.menu_Content_alpha); fader.StartFadeIn(); - + CInfoClock::getInstance()->ClearDisplay(); paint(); int oldselected = selected; @@ -947,8 +942,6 @@ int CChannelList::show() printf("CChannelList:: bouquetList->exec res %d\n", res); } - if (headerClock) - headerClock->Stop(); if(NeutrinoMessages::mode_ts == CNeutrinoApp::getInstance()->getMode()) return -1; @@ -968,12 +961,17 @@ void CChannelList::hide() delete cc_minitv; cc_minitv = NULL; } - if (headerClock) { - if (headerClock->Stop()) - headerClock->hide(); + + header->kill(); + if (CChannelLogo){ + CChannelLogo->kill(); + delete CChannelLogo; + CChannelLogo = NULL; } + frameBuffer->paintBackgroundBoxRel(x, y, full_width, height + info_height); clearItem2DetailsLine(); + CInfoClock::getInstance()->enableInfoClock(!CInfoClock::getInstance()->isBlocked()); } bool CChannelList::showInfo(int number, int epgpos) @@ -1699,6 +1697,7 @@ void CChannelList::showChannelLogo() //TODO: move into an own handler, eg. heade CChannelLogo->setYPos(y + (theight - CChannelLogo->getHeight()) / 2); CChannelLogo->paint(); } else { + CChannelLogo->hide(); delete CChannelLogo; CChannelLogo = NULL; } @@ -2078,51 +2077,68 @@ void CChannelList::paint() void CChannelList::paintHead() { - static int gradient_head = g_settings.theme.menu_Head_gradient; - static int gradient_c2c = g_settings.theme.gradient_c2c; + if (header == NULL) + header = new CComponentsHeader(); + + header->setDimensionsAll(x, y, full_width, theight); - CComponentsHeader header(x, y, full_width, theight, name /*no header icon*/); if (bouquet && bouquet->zapitBouquet && bouquet->zapitBouquet->bLocked != g_settings.parentallock_defaultlocked) - header.setIcon(NEUTRINO_ICON_LOCK); - if (edit_state) - header.setCaption(std::string(g_Locale->getText(LOCALE_CHANNELLIST_EDIT)) + ": " + name); + header->setIcon(NEUTRINO_ICON_LOCK); - header.paint(CC_SAVE_SCREEN_NO); + string header_txt = !edit_state ? name : string(g_Locale->getText(LOCALE_CHANNELLIST_EDIT)) + ": " + name; + fb_pixel_t header_txt_col = (edit_state ? COL_RED : COL_MENUHEAD_TEXT); + header->setColorBody(COL_MENUHEAD_PLUS_0); - if ((gradient_head != g_settings.theme.menu_Head_gradient || gradient_c2c != g_settings.theme.gradient_c2c) && headerClock != NULL) { - gradient_head = g_settings.theme.menu_Head_gradient; - gradient_c2c = g_settings.theme.gradient_c2c; - headerClock->clearSavedScreen(); - delete headerClock; - headerClock = NULL; + header->setCaption(header_txt, CTextBox::NO_AUTO_LINEBREAK, header_txt_col); + + if (header->enableColBodyGradient(g_settings.theme.menu_Head_gradient, COL_MENUCONTENT_PLUS_0)){ + if (CChannelLogo) + CChannelLogo->clearFbData(); } if (timeset) { - if (headerClock == NULL) { - headerClock = new CComponentsFrmClock(0, 0, 0, 0, "%H:%M", true); - headerClock->setClockBlink("%H %M"); - headerClock->setClockIntervall(1); - headerClock->doPaintBg(!gradient_head); - headerClock->enableTboxSaveScreen(gradient_head); - headerClock->setCorner(RADIUS_LARGE, CORNER_TOP_RIGHT); - } - headerClock->setClockFont(SNeutrinoSettings::FONT_TYPE_MENU_TITLE); - headerClock->setYPos(y); - headerClock->setHeight(theight); - headerClock->setTextColor(header.getTextObject()->getTextColor()); - headerClock->setColorBody(header.getColorBody()); - headerClock->refresh(); - headerClockWidth = headerClock->getWidth(); - headerClock->setXPos(x + full_width - headerClockWidth - 10); - headerClockWidth += 6; + if(!edit_state){ + if (header->getContextBtnObject()) + if (!header->getContextBtnObject()->empty()) + header->removeContextButtons(); + header->enableClock(true, "%H:%M", "%H %M", true); + logo_off = header->getClockObject()->getWidth() + 10; - headerClock->Start(); + header->getClockObject()->setCorner(RADIUS_LARGE, CORNER_TOP_RIGHT); + }else{ + if (header->getClockObject()){ + header->disableClock(); + header->setContextButton(CComponentsHeader::CC_BTN_EXIT); + } + } } else - headerClockWidth = 0; + logo_off = 10; - logo_off = headerClockWidth + 10; - headerNew = true; + header->paint(CC_SAVE_SCREEN_NO); +} + +CComponentsHeader* CChannelList::getHeaderObject() +{ + return header; +} + +void CChannelList::ResetModules() +{ + delete header; + header = NULL; + if(dline){ + delete dline; + dline = NULL; + } + if (cc_minitv){ + delete cc_minitv; + cc_minitv = NULL; + } + if (CChannelLogo) { + delete CChannelLogo; + CChannelLogo = NULL; + } } void CChannelList::paintBody() diff --git a/src/gui/channellist.h b/src/gui/channellist.h index 580371cd8..96014b6b4 100644 --- a/src/gui/channellist.h +++ b/src/gui/channellist.h @@ -75,7 +75,7 @@ private: bool edit_state; CFrameBuffer *frameBuffer; - CComponentsPIP *cc_minitv; + unsigned int selected, selected_in_new_mode; unsigned int origPosition; unsigned int newPosition; @@ -127,7 +127,7 @@ private: int ChannelList_Rec; - CComponentsChannelLogoScalable* CChannelLogo; + bool headerNew; void paintDetails(int index); @@ -243,5 +243,7 @@ public: unsigned Size() { return (*chanlist).size(); } ZapitChannelList &getChannels() { return channels; }; bool checkLockStatus(neutrino_msg_data_t data, bool pip = false); + CComponentsHeader* getHeaderObject(); + void ResetModules(); }; #endif diff --git a/src/gui/components/Makefile.am b/src/gui/components/Makefile.am index 7f0a50687..7f855cf03 100644 --- a/src/gui/components/Makefile.am +++ b/src/gui/components/Makefile.am @@ -27,6 +27,8 @@ noinst_LIBRARIES = libneutrino_gui_components.a libneutrino_gui_components_a_SOURCES = \ cc_base.cpp \ cc_detailsline.cpp \ + cc_draw.cpp \ + cc_extra.cpp \ cc_frm_button.cpp \ cc_frm.cpp \ cc_frm_chain.cpp \ diff --git a/src/gui/components/cc.h b/src/gui/components/cc.h index d7f08650d..edbadbada 100644 --- a/src/gui/components/cc.h +++ b/src/gui/components/cc.h @@ -3,7 +3,7 @@ Copyright (C) 2001 by Steffen Hehn 'McClean' Classes for generic GUI-related components. - Copyright (C) 2013, Thilo Graf 'dbt' + Copyright (C) 2013-2015, Thilo Graf 'dbt' License: GPL @@ -17,10 +17,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - Boston, MA 02110-1301, USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ /// Basic CComponent class header. @@ -33,6 +31,7 @@ Basic attributes and member functions for component sub classes #include "cc_types.h" #include "cc_base.h" +#include "cc_extra.h" #include "cc_item_infobox.h" #include "cc_item_picture.h" @@ -43,7 +42,6 @@ Basic attributes and member functions for component sub classes #include "cc_detailsline.h" #include "cc_frm_scrollbar.h" -#include "cc_frm.h" #include "cc_frm_chain.h" #include "cc_frm_button.h" #include "cc_frm_clock.h" diff --git a/src/gui/components/cc_base.cpp b/src/gui/components/cc_base.cpp index c5080b8fc..1820de466 100644 --- a/src/gui/components/cc_base.cpp +++ b/src/gui/components/cc_base.cpp @@ -3,7 +3,7 @@ Copyright (C) 2001 by Steffen Hehn 'McClean' Classes for generic GUI-related components. - Copyright (C) 2012-2014, Thilo Graf 'dbt' + Copyright (C) 2012-2015, Thilo Graf 'dbt' Copyright (C) 2012, Michael Liebmann 'micha-bbg' License: GPL @@ -18,10 +18,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - Boston, MA 02110-1301, USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H @@ -31,304 +29,11 @@ #include #include #include "cc_base.h" -#include -#include + using namespace std; //abstract basic class CComponents -CComponents::CComponents() : COSDFader(g_settings.theme.menu_Content_alpha) +CComponents::CComponents() { - x = saved_screen.x = 0; - y = saved_screen.y = 0; - cc_xr = x; - cc_yr = y; - height = saved_screen.dy = CC_HEIGHT_MIN; - width = saved_screen.dx = CC_WIDTH_MIN; - - col_body = COL_MENUCONTENT_PLUS_0; - col_shadow = COL_MENUCONTENTDARK_PLUS_0; - col_frame = COL_MENUCONTENT_PLUS_6; - col_frame_sel = COL_MENUCONTENTSELECTED_PLUS_0; - corner_type = CORNER_ALL; - corner_rad = 0; cc_tag = NULL; - shadow = CC_SHADOW_OFF; - shadow_w = SHADOW_OFFSET; - fr_thickness = 0; - fr_thickness_sel = 3; - - firstPaint = true; - is_painted = false; - paint_bg = true; - save_tbox_screen = false; - cc_allow_paint = true; - frameBuffer = CFrameBuffer::getInstance(); - v_fbdata.clear(); - saved_screen.pixbuf = NULL; - col_body_gradient = false; - cc_body_gradient_c2c = true; - cc_body_gradient_2nd_col= COL_MENUCONTENT_PLUS_0; - cc_gradientData.gradientBuf = NULL; - cc_gradientData.boxBuf = NULL; -} - -CComponents::~CComponents() -{ - hide(); - clearSavedScreen(); - clearFbData(); - if (cc_gradientData.gradientBuf) - free(cc_gradientData.gradientBuf); - if (cc_gradientData.boxBuf) - cs_free_uncached(cc_gradientData.boxBuf); -} - -void CComponents::clearSavedScreen() -{ - if (saved_screen.pixbuf) - delete[] saved_screen.pixbuf; - saved_screen.pixbuf = NULL; -} - -bool CComponents::CheckFbData(const comp_fbdata_t& fbdata, const char* func, const int line) -{ - int32_t rows = fbdata.dx / (int32_t)frameBuffer->getScreenWidth(true) - 1 + fbdata.y; - int32_t rest = fbdata.dx % (int32_t)frameBuffer->getScreenWidth(true); - int32_t end = rows * (int32_t)frameBuffer->getScreenWidth(true) + rest; - if ( (fbdata.x < 0 || fbdata.y < 0) || - (end >= (int32_t)frameBuffer->getScreenWidth(true)*(int32_t)frameBuffer->getScreenHeight(true)) - ) { - dprintf(DEBUG_NORMAL, "[CComponents] ERROR! Position < 0 or > FB end [%s - %d]\n\tx = %d y = %d\n\tdx = %d dy = %d\n", - func, line, - fbdata.x, fbdata.y, - fbdata.dx, fbdata.dy); - return false; - } - if (fbdata.dx == 0 || fbdata.dy == 0) { - dprintf(DEBUG_DEBUG,"[CComponents] INFO! dx and/or dy = 0 [%s - %d]\n\tx = %d y = %d\n\tdx = %d dy = %d\n", - func, line, - fbdata.x, fbdata.y, - fbdata.dx, fbdata.dy); - return false; - } - return true; -} - -//paint framebuffer stuff and fill buffer -void CComponents::paintFbItems(bool do_save_bg) -{ - //save background before first paint, do_save_bg must be true - if (firstPaint && do_save_bg){ - for(size_t i=0; isave screen: %d, fbdata_type: %d\n\tx = %d\n\ty = %d\n\tdx = %d\n\tdy = %d\n", - __func__, - __LINE__, - firstPaint, - v_fbdata[i].fbdata_type, - v_fbdata[i].x, - v_fbdata[i].y, - v_fbdata[i].dx, - v_fbdata[i].dy); - - saved_screen.x = v_fbdata[i].x; - saved_screen.y = v_fbdata[i].y; - saved_screen.dx = v_fbdata[i].dx; - saved_screen.dy = v_fbdata[i].dy; - clearSavedScreen(); - saved_screen.pixbuf = getScreen(saved_screen.x, saved_screen.y, saved_screen.dx, saved_screen.dy); - firstPaint = false; - break; - } - } - - for(size_t i=0; i< v_fbdata.size(); i++){ - // Don't paint on dimension or position error dx or dy are 0 - if (!CheckFbData(v_fbdata[i], __func__, __LINE__)){ - continue; - } - int fbtype = v_fbdata[i].fbdata_type; - - dprintf(DEBUG_DEBUG, "[CComponents]\n\t[%s - %d], fbdata_[%d]\n\tx = %d\n\ty = %d\n\tdx = %d\n\tdy = %d\n", - __func__, - __LINE__, - (int)i, - v_fbdata[i].x, - v_fbdata[i].y, - v_fbdata[i].dx, - v_fbdata[i].dy); - - //some elements can be assembled from lines and must be handled as one unit (see details line), - //so all individual backgrounds of boxes must be saved and painted in "firstpaint mode" -#if 0 - if (firstPaint){ - - if (do_save_bg && fbtype == CC_FBDATA_TYPE_LINE) - v_fbdata[i].pixbuf = getScreen(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy); - - //ensure painting of all line fb items with saved screens - if (fbtype == CC_FBDATA_TYPE_LINE) - firstPaint = true; - else - firstPaint = false; - } -#endif - if (do_save_bg && fbtype == CC_FBDATA_TYPE_LINE) - v_fbdata[i].pixbuf = getScreen(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy); - - //paint all fb relevant basic parts (frame and body) with all specified properties, paint_bg must be true - if (fbtype != CC_FBDATA_TYPE_BGSCREEN && paint_bg){ - if (fbtype == CC_FBDATA_TYPE_FRAME) { - if (v_fbdata[i].frame_thickness > 0 && cc_allow_paint) - frameBuffer->paintBoxFrame(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy, v_fbdata[i].frame_thickness, v_fbdata[i].color, v_fbdata[i].r, corner_type); - } - else if (fbtype == CC_FBDATA_TYPE_BACKGROUND) - frameBuffer->paintBackgroundBoxRel(x, y, v_fbdata[i].dx, v_fbdata[i].dy); - else if (fbtype == CC_FBDATA_TYPE_SHADOW_BOX) { - if (shadow) { - int sw = shadow_w; - int sw_cur = sw; - int x_sh = v_fbdata[i].x + v_fbdata[i].dx - sw; - int y_sh = v_fbdata[i].y + v_fbdata[i].dy - sw; - if (corner_type && v_fbdata[i].r) { - //calculate positon of shadow areas - x_sh += sw - 2*v_fbdata[i].r; - y_sh += sw - 2*v_fbdata[i].r; - //calculate current shadow width depends of current corner_rad - sw_cur = max(2*v_fbdata[i].r, sw); - } - if (cc_allow_paint && !is_painted){ - // shadow right - frameBuffer->paintBoxRel(x_sh, v_fbdata[i].y, sw_cur, v_fbdata[i].dy-sw_cur, v_fbdata[i].color, v_fbdata[i].r, corner_type & CORNER_TOP_RIGHT); - // shadow bottom - frameBuffer->paintBoxRel(v_fbdata[i].x, y_sh, v_fbdata[i].dx, sw_cur, v_fbdata[i].color, v_fbdata[i].r, corner_type & CORNER_BOTTOM); - } - } - } - else { - if(cc_allow_paint) { - if (col_body_gradient && (v_fbdata[i].fbdata_type == CC_FBDATA_TYPE_BOX) && (v_fbdata[i].data != NULL)) { - // color gradient - gradientData_t *gradientData = static_cast (v_fbdata[i].data); - if (gradientData->boxBuf == NULL) - gradientData->boxBuf = frameBuffer->paintBoxRel(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy, 0, gradientData, v_fbdata[i].r, corner_type); - else -// frameBuffer->blit2FB(gradientData->boxBuf, v_fbdata[i].dx, v_fbdata[i].dy, v_fbdata[i].x, v_fbdata[i].y); - frameBuffer->blitBox2FB(gradientData->boxBuf, v_fbdata[i].dx, v_fbdata[i].dy, v_fbdata[i].x, v_fbdata[i].y); - } else - frameBuffer->paintBoxRel(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy, v_fbdata[i].color, v_fbdata[i].r, corner_type); - } - } - } - } - - is_painted = true; -} - -//screen area save -inline fb_pixel_t* CComponents::getScreen(int ax, int ay, int dx, int dy) -{ - if (dx * dy == 0) - return NULL; - - fb_pixel_t* pixbuf = new fb_pixel_t[dx * dy]; - frameBuffer->waitForIdle("CComponents::getScreen()"); - frameBuffer->SaveScreen(ax, ay, dx, dy, pixbuf); - return pixbuf; -} - -//restore screen from buffer -inline void CComponents::hide() -{ - for(size_t i =0; i< v_fbdata.size() ;i++) { - if (v_fbdata[i].pixbuf){ - frameBuffer->waitForIdle("CComponents::hide()"); - frameBuffer->RestoreScreen(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy, v_fbdata[i].pixbuf); - } - } - - clearFbData(); - is_painted = false; -} - -//erase or paint over rendered objects -void CComponents::kill(const fb_pixel_t& bg_color, const int& corner_radius) -{ - for(size_t i =0; i< v_fbdata.size() ;i++){ -#if 0 - if (bg_color != COL_BACKGROUND_PLUS_0) -#endif - int r = v_fbdata[i].r; - if (corner_radius > -1) - r = corner_radius; - frameBuffer->paintBoxRel(v_fbdata[i].x, - v_fbdata[i].y, - v_fbdata[i].dx, - v_fbdata[i].dy, - bg_color, - r, - corner_type); - if (v_fbdata[i].frame_thickness) - frameBuffer->paintBoxFrame(v_fbdata[i].x, - v_fbdata[i].y, - v_fbdata[i].dx, - v_fbdata[i].dy, - v_fbdata[i].frame_thickness, - bg_color, - r, - corner_type); - -#if 0 - else - frameBuffer->paintBackgroundBoxRel(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy); -#endif - } - clearFbData(); - firstPaint = true; - is_painted = false; -} - -//clean old screen buffer -void CComponents::clearFbData() -{ - for(size_t i =0; i< v_fbdata.size() ;i++) { - if (v_fbdata[i].pixbuf) - delete[] v_fbdata[i].pixbuf; - -#if 0 - if (v_fbdata[i].data && (v_fbdata[i].fbdata_type == CC_FBDATA_TYPE_BOX)) { - gradientData_t *gradientData = static_cast (v_fbdata[i].data); - if (gradientData->boxBuf) - cs_free_uncached(gradientData->boxBuf); - } -#endif - } - v_fbdata.clear(); -} - -inline void CComponents::setXPos(const int& xpos) -{ - x = xpos; -} - -inline void CComponents::setYPos(const int& ypos) -{ - y = ypos; -} - -void CComponents::setFrameThickness(const int& thickness, const int& thickness_sel) -{ - fr_thickness = thickness; - - if (fr_thickness_sel != thickness_sel) - fr_thickness_sel = thickness_sel; -} - - -void CComponents::enableColBodyGradient(bool do_paint_gradient) -{ - col_body_gradient = do_paint_gradient; } diff --git a/src/gui/components/cc_base.h b/src/gui/components/cc_base.h index 38663aeac..b697deda6 100644 --- a/src/gui/components/cc_base.h +++ b/src/gui/components/cc_base.h @@ -3,7 +3,8 @@ Copyright (C) 2001 by Steffen Hehn 'McClean' Classes for generic GUI-related components. - Copyright (C) 2012-2014, Thilo Graf 'dbt' + Copyright (C) 2012-2015, Thilo Graf 'dbt' + Copyright (C) 2012, Michael Liebmann 'micha-bbg' License: GPL @@ -17,362 +18,38 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - Boston, MA 02110-1301, USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ -#ifndef __COMPONENTS__ -#define __COMPONENTS__ +#ifndef __CC_BASE__ +#define __CC_BASE__ #include "cc_types.h" #include "cc_signals.h" -#include -#include -#include -#include -#include -#include -#include +#include "cc_draw.h" + /// Basic component class. /*! Basic attributes and member functions for component sub classes */ -class CComponents : public CComponentsSignals, public COSDFader +class CComponents : public CComponentsSignals, public CCDraw { - private: - ///pixel buffer handling, returns pixel buffer depends of given parameters - fb_pixel_t* getScreen(int ax, int ay, int dx, int dy); - protected: - ///object: framebuffer object, usable in all sub classes - CFrameBuffer * frameBuffer; - ///container: for frambuffer properties and pixel buffer - std::vector v_fbdata; - - ///property: x-position on screen, to alter with setPos() or setDimensionsAll(), see also defines CC_APPEND, CC_CENTERED - int x; - ///property: y-position on screen, to alter setPos() or setDimensionsAll(), see also defines CC_APPEND, CC_CENTERED - int y; - ///property: contains real x-position on screen - int cc_xr; - ///property: contains real y-position on screen - int cc_yr; - ///property: height-dimension on screen, to alter with setHeight() or setDimensionsAll() - int height; - ///property: width-dimension on screen, to alter with setWidth() or setDimensionsAll() - int width; - ///property: has corners with definied type, types are defined in /driver/frambuffer.h, without effect, if corner_radius=0 - int corner_type; - ///property: defined radius of corner, without effect, if corner_type=0 - int corner_rad; - ///property: tag for component, can contain any value if required, default value is NULL, you can fill with a cast, see also setTag() and getTag() + + ///property: tag for component, can contains any value if required, default value is NULL, you can fill with a cast, see also setTag() and getTag() void *cc_tag; - ///property: color of body - fb_pixel_t col_body; - fb_pixel_t old_gradient_color; - int old_gradient_c2c; - ///property: color of shadow - fb_pixel_t col_shadow; - ///property: color of frame - fb_pixel_t col_frame; - ///property: color of frame if component is selected, Note: fr_thickness_sel must be set - fb_pixel_t col_frame_sel; - ///property: contains data for gradiant handling - gradientData_t cc_gradientData; - ///property: true component can paint gradient, see also enableColBodyGradient() - bool col_body_gradient; - ///property: background gradient mode - int cc_body_gradient_mode; - ///property: background gradient intensity - int cc_body_gradient_intensity; - ///property: background gradient intensity value min - uint8_t cc_body_gradient_intensity_v_min; - ///property: background gradient intensity value max - uint8_t cc_body_gradient_intensity_v_max; - ///property: background gradient saturation - uint8_t cc_body_gradient_saturation; - ///property: background gradient direction - int cc_body_gradient_direction; - ///property: background gradient mode - bool cc_body_gradient_c2c; - ///property: background gradient 2nd color - fb_pixel_t cc_body_gradient_2nd_col; - - ///property: true=component has shadow - bool shadow; - ///property: width of shadow - int shadow_w; - - ///property: frame thickness, see also setFrameThickness() - int fr_thickness; - ///property: frame thickness of selected component, see also setFrameThickness() - int fr_thickness_sel; - - ///status: true=component was painted for 1st time - bool firstPaint; - ///status: true=component was rendered - bool is_painted; - ///mode: true=activate rendering of basic elements (frame, shadow and body) - bool paint_bg; - bool save_tbox_screen; - ///mode: true=allows painting of item, see also allowPaint() - bool cc_allow_paint; - - ///rendering of framebuffer elements at once, - ///elements are contained in v_fbdata, presumes added frambuffer elements with paintInit(), - ///parameter do_save_bg=true, saves background of element to pixel buffer, this can be restore with hide() - void paintFbItems(bool do_save_bg = true); - - ///check current fbdtata position and dimensions, parameter fbdata is an element of v_fbdata, returns false on error - bool CheckFbData(const comp_fbdata_t& fbdata, const char* func, const int line); - - ///clean up old screen buffer saved in v_fbdata - virtual void clearFbData(); - - ///container: contains saved pixel buffer with position and dimensions - comp_screen_data_t saved_screen; - public: ///basic component class constructor. CComponents(); - virtual~CComponents(); - - ///set screen x-position, parameter as int - virtual void setXPos(const int& xpos); - ///set screen y-position, parameter as int - virtual void setYPos(const int& ypos); - ///set x and y position at once - ///Note: position of bound components (items) means position related within parent form, not for screen! - ///to set the real screen position, look at setRealPos() - inline virtual void setPos(const int& xpos, const int& ypos){x = xpos; y = ypos;}; - - ///sets real x position on screen. Use this, if item is added to a parent form - virtual void setRealXPos(const int& xr){cc_xr = xr;}; - ///sets real y position on screen. Use this, if item is added to a parent form - virtual void setRealYPos(const int& yr){cc_yr = yr;}; - ///sets real x and y position on screen at once. Use this, if item is added to a parent form - virtual void setRealPos(const int& xr, const int& yr){cc_xr = xr; cc_yr = yr;}; - ///get real x-position on screen. Use this, if item contains own render methods and item is bound to a form - virtual int getRealXPos(){return cc_xr;}; - ///get real y-position on screen. Use this, if item contains own render methods and item is bound to a form - virtual int getRealYPos(){return cc_yr;}; - - ///set height of component on screen - inline virtual void setHeight(const int& h){height = h;}; - ///set width of component on screen - inline virtual void setWidth(const int& w){width = w;}; - ///set all positions and dimensions of component at once - inline virtual void setDimensionsAll(const int& xpos, const int& ypos, const int& w, const int& h){x = xpos; y = ypos; width = w; height = h;}; - - ///return screen x-position of component - ///Note: position of bound components (items) means position related within parent form, not for screen! - ///to get the real screen position, use getRealXPos(), to find in CComponentsItem sub classes - inline virtual int getXPos(){return x;}; - ///return screen y-position of component - ///Note: position of bound components (items) means position related within parent form, not for screen! - ///to get the real screen position, use getRealYPos(), to find in CComponentsItem sub classes - inline virtual int getYPos(){return y;}; - ///return height of component - inline virtual int getHeight(){return height;}; - ///return width of component - inline virtual int getWidth(){return width;}; - ///return of frame thickness - inline virtual int getFrameThickness(){return fr_thickness;}; - - ///return/set (pass through) width and height of component - inline virtual void getSize(int* w, int* h){*w=width; *h=height;}; - ///return/set (pass through) position and dimensions of component at once - inline virtual void getDimensions(int* xpos, int* ypos, int* w, int* h){*xpos=x; *ypos=y; *w=width; *h=height;}; + virtual~CComponents(){}; ///sets tag as void*, see also cc_tag virtual void setTag(void* tag){cc_tag = tag;}; ///gets tag as void*, see also cc_tag - inline virtual void* getTag(){return cc_tag;}; - - ///set frame color - inline virtual void setColorFrame(fb_pixel_t color){col_frame = color;}; - ///set selected frame color - inline virtual void setColorFrameSel(fb_pixel_t color){col_frame_sel = color;}; - ///set body color - inline virtual void setColorBody(fb_pixel_t color){col_body = color;}; - ///set shadow color - inline virtual void setColorShadow(fb_pixel_t color){col_shadow = color;}; - ///set all basic framebuffer element colors at once - ///Note: Possible color values are defined in "gui/color.h" and "gui/customcolor.h" - inline virtual void setColorAll(fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow){col_frame = color_frame; col_body = color_body; col_shadow = color_shadow;}; - ///set color gradient on/off - virtual void enableColBodyGradient(bool do_paint_gradient); - ///set color gradient properties, possible parameter values for mode and intensity to find in CColorGradient, in driver/framebuffer.h> - virtual void setColBodyGradient(const int& mode, const int& direction, const int& intensity = CColorGradient::normal, uint8_t v_min=0x40, uint8_t v_max=0xE0, uint8_t s=0xC0) - { cc_body_gradient_mode = mode; - cc_body_gradient_direction = direction; - cc_body_gradient_intensity=intensity; - cc_body_gradient_intensity_v_min=v_min; - cc_body_gradient_intensity_v_max=v_max; - cc_body_gradient_saturation=s; }; - - virtual void set2ndColor(fb_pixel_t col_2nd){ cc_body_gradient_c2c = true; cc_body_gradient_2nd_col = col_2nd;}; - - ///get frame color - inline virtual fb_pixel_t getColorFrame(){return col_frame;}; - ///get body color - inline virtual fb_pixel_t getColorBody(){return col_body;}; - ///get shadow color - inline virtual fb_pixel_t getColorShadow(){return col_shadow;}; - - ///set corner types - ///Possible corner types are defined in CFrameBuffer (see: driver/framebuffer.h) - ///Note: default values are given from settings - inline virtual void setCornerType(const int& type){corner_type = type;}; - ///set corner radius and type - inline virtual void setCorner(const int& radius, const int& type = CORNER_ALL){corner_rad = radius; corner_type = type;}; - ///get corner types - inline virtual int getCornerType(){return corner_type;}; - ///get corner radius - inline virtual int getCornerRadius(){return corner_rad;}; - - ///set frame thickness - virtual void setFrameThickness(const int& thickness, const int& thickness_sel = 3); - ///switch shadow on/off - ///Note: it's recommended to use #defines: CC_SHADOW_ON=true or CC_SHADOW_OFF=false as parameter, see also cc_types.h - inline virtual void setShadowOnOff(bool has_shadow){shadow = has_shadow;}; - - ///hide current screen and restore background - virtual void hide(); - - ///erase or paint over rendered objects without restore of background, it's similar to paintBackgroundBoxRel() known - ///from CFrameBuffer but with possiblity to define color, default color is COL_BACKGROUND_PLUS_0 (empty background) - virtual void kill(const fb_pixel_t& bg_color = COL_BACKGROUND_PLUS_0, const int& corner_radius = -1); - - ///returns paint mode, true=item was painted - virtual bool isPainted(){return is_painted;} - ///allows paint of elementary item parts (shadow, frame and body), similar as background, set it usually to false, if item used in a form - virtual void doPaintBg(bool do_paint){paint_bg = do_paint;}; - // enable/disable CTextBox screen saving on paint - virtual void enableTboxSaveScreen(bool enable){ save_tbox_screen = enable; }; - - ///allow/disalows paint of item and its contents, but initialize of other properties are not touched - ///this can be understood as a counterpart to isPainted(), but before paint and value of is_painted is modified temporarily till next paint of item //TODO: is this sufficiently? - void allowPaint(bool allow){cc_allow_paint = allow; is_painted = cc_allow_paint ? false : true;}; - ///returns visibility mode - virtual bool paintAllowed(){return cc_allow_paint;}; - - ///cleans saved pixel buffer - virtual void clearSavedScreen(); -}; - -class CComponentsItem : public CComponents -{ - protected: - ///property: define of item type, see cc_types.h for possible types - int cc_item_type; - ///property: define of item index, all bound items get an index, - ///default: CC_NO_INDEX as identifer for not embedded item and default index=0 for form as main parent - ///see also getIndex(), setIndex() - int cc_item_index; - ///property: default enabled - bool cc_item_enabled; - ///property: default not selected - bool cc_item_selected; - ///property: page number, this defines current item page location, means: this item is embedded in a parent container on page number n, see also setPageNumber() - ///default value is 0 for page one, any value > 0 causes handling for mutilple pages at parent container - uint8_t cc_page_number; - ///specifies that some certain operations especially eg. exec events for that item are possible, see also setFocus(), hasFocus() - bool cc_has_focus; - - ///Pointer to the form object in which this item is embedded. - ///Is typically the type CComponentsForm or derived classes, default intialized with NULL - CComponentsForm *cc_parent; - - ///hides item, arg: no_restore=true causes no restore of background, but clean up pixel buffer if required - void hideCCItem(bool no_restore = false); - - ///initialze of basic framebuffer elements with shadow, background and frame. - ///must be called first in all paint() members before paint any item, - ///If backround is not required, it's possible to override this with variable paint_bg=false, use doPaintBg(true/false) to set this! - ///arg do_save_bg=false avoids using of unnecessary pixel memory, eg. if no hide with restore is provided. This is mostly the case whenever - ///an item will be hide or overpainted with other methods, or it's embedded (bound) in a parent form. - void paintInit(bool do_save_bg); - - ///add "this" current item to parent - void initParent(CComponentsForm* parent); - - - public: - CComponentsItem(CComponentsForm *parent = NULL); - - ///sets pointer to the form object in which this item is embedded. - virtual void setParent(CComponentsForm *parent){cc_parent = parent;}; - ///returns pointer to the form object in which this item is embedded. - virtual CComponentsForm* getParent(){return cc_parent;}; - ///property: returns true if item is added to a form - virtual bool isAdded(); - ///indicates wether item has focus - virtual bool hasFocus(){return cc_has_focus;} - ///set or unset focus of item, stand alone items without parent have always set focus to true, inside of a parent form object, always the last added item has focus - virtual void setFocus(bool focus); - - ///abstract: paint item, arg: do_save_bg see paintInit() above - virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES) = 0; - ///hides item, arg: no_restore see hideCCItem() above - virtual void hide(bool no_restore = false); - - ///erase or paint over rendered objects without restore of background, it's similar to paintBackgroundBoxRel() known - ///from CFrameBuffer but with possiblity to define color, default color is 0 (empty background) - ///NOTE: Items with parent binding use the parent background color as default! Set parameter 'ignore_parent=true' to ignore parent background color! - virtual void kill(const fb_pixel_t& bg_color = COL_BACKGROUND_PLUS_0, bool ignore_parent = false); - - ///get the current item type, see attribute cc_item_type above - virtual int getItemType(); - ///syncronizes item colors with current color settings if required, NOTE: overwrites internal values! - virtual void syncSysColors(); - - ///set select mode, see also col_frame_sel - virtual void setSelected(bool selected){cc_item_selected = selected;}; - ///set enable mode, see also cc_item_enabled - virtual void setEnable(bool enabled){cc_item_enabled = enabled;}; - - ///get select mode, see also setSelected() above - virtual bool isSelected(){return cc_item_selected;}; - ///get enable mode, see also setEnable() above - virtual bool isEnabled(){return cc_item_enabled;}; - - ///get current index of item, see also attribut cc_item_index - virtual int getIndex(){return cc_item_index;}; - ///set an index to item, see also attribut cc_item_index. - ///To generate an index, use genIndex() - virtual void setIndex(const int& index){cc_item_index = index;}; - - ///sets page location of current item, parameter as uint8_t, see: cc_page_number - virtual void setPageNumber(const uint8_t& on_page_number){cc_page_number = on_page_number;}; - ///returns current number of page location of current item, see: cc_page_number - virtual u_int8_t getPageNumber(){return cc_page_number;}; - - ///set screen x-position, parameter as int - virtual void setXPos(const int& xpos); - ///set screen y-position, parameter as int - virtual void setYPos(const int& ypos); - ///set screen x-position, parameter as uint8_t, percent x value related to current width of parent form or screen - virtual void setXPosP(const uint8_t& xpos_percent); - ///set screen y-position, parameter as uint8_t, percent y value related to current height of parent form or screen - virtual void setYPosP(const uint8_t& ypos_percent); - ///set x and y position as percent value related to current parent form or screen dimensions at once - virtual void setPosP(const uint8_t& xpos_percent, const uint8_t& ypos_percent); - - ///do center item on screen or within a parent form, parameter along_mode assigns direction of centering - virtual void setCenterPos(int along_mode = CC_ALONG_X | CC_ALONG_Y); - - ///set item height, parameter as uint8_t, as percent value related to current height of parent form or screen - virtual void setHeightP(const uint8_t& h_percent); - ///set item width, parameter as uint8_t, as percent value related to current width of parent form or screen - virtual void setWidthP(const uint8_t& w_percent); - - ///sub: init body color gradient - virtual void initBodyGradient(); + virtual void* getTag(){return cc_tag;}; }; #endif diff --git a/src/gui/components/cc_detailsline.cpp b/src/gui/components/cc_detailsline.cpp index 6a032d454..843ebddcf 100644 --- a/src/gui/components/cc_detailsline.cpp +++ b/src/gui/components/cc_detailsline.cpp @@ -31,6 +31,7 @@ #include #include #include "cc_detailsline.h" +#include "cc_draw.h" using namespace std; @@ -61,6 +62,7 @@ void CComponentsDetailLine::initVarDline( const int& x_pos, const int& y_pos_top //CComponentsDetailLine thickness = 4; + cc_body_gradient_enable = false; } CComponentsDetailLine::~CComponentsDetailLine() @@ -85,41 +87,50 @@ CComponentsDetailLine::~CComponentsDetailLine() //paint details line with current parameters void CComponentsDetailLine::paint(bool do_save_bg) { - clearFbData(); + cc_save_bg = do_save_bg; - int y_mark_top = y-h_mark_top/2+thickness/2; - int y_mark_down = y_down-h_mark_down/2+thickness/2; + hide(); + if (hasChanges()) + clearFbData(); - int sw = shadow_w; + if (v_fbdata.empty()){ - comp_fbdata_t fbdata[] = - { - /* vertical item mark | */ - {CC_FBDATA_TYPE_LINE, x+width-thickness-sw, y_mark_top, thickness, h_mark_top, col_body, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_LINE, x+width-sw, y_mark_top+sw, sw, h_mark_top-sw, col_shadow, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_LINE, x+width-thickness, y_mark_top+h_mark_top, thickness, sw, col_shadow, 0, 0, NULL, NULL}, + int y_mark_top = y-h_mark_top/2+thickness/2; + int y_mark_down = y_down-h_mark_down/2+thickness/2; - /* horizontal item line - */ - {CC_FBDATA_TYPE_LINE, x, y, width-thickness-sw, thickness, col_body, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_LINE, x+thickness, y+thickness, width-2*thickness-sw, sw, col_shadow, 0, 0, NULL, NULL}, + int sw = shadow_w; - /* vertical connect line [ */ - {CC_FBDATA_TYPE_LINE, x, y+thickness, thickness, y_down-y-thickness, col_body, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_LINE, x+thickness, y+thickness+sw, sw, y_down-y-thickness-sw, col_shadow, 0, 0, NULL, NULL}, + cc_fbdata_t fbdata[] = + { + /*buffered bg full width and height */ + {true, CC_FBDATA_TYPE_BGSCREEN, x, y_mark_top, width, y_mark_down-y_mark_top+h_mark_down, 0, 0, 0, 0, NULL, NULL, NULL, false}, - /* horizontal info line - */ - {CC_FBDATA_TYPE_LINE, x, y_down, width-thickness-sw, thickness, col_body, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_LINE, x+sw, y_down+thickness, width-thickness-2*sw, sw, col_shadow, 0, 0, NULL, NULL}, + /* vertical item mark | */ + {true, CC_FBDATA_TYPE_BOX, x+width-thickness-sw, y_mark_top, thickness, h_mark_top, col_body, 0, 0, 0, NULL, NULL, NULL, false}, + {true, CC_FBDATA_TYPE_BOX, x+width-sw, y_mark_top+sw, sw, h_mark_top-sw, col_shadow, 0, 0, 0, NULL, NULL, NULL, false}, + {true, CC_FBDATA_TYPE_BOX, x+width-thickness, y_mark_top+h_mark_top, thickness, sw, col_shadow, 0, 0, 0, NULL, NULL, NULL, false}, - /* vertical info mark | */ - {CC_FBDATA_TYPE_LINE, x+width-thickness-sw, y_mark_down, thickness, h_mark_down, col_body, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_LINE, x+width-sw, y_mark_down+sw, sw, h_mark_down-sw, col_shadow, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_LINE, x+width-thickness, y_mark_down+h_mark_down,thickness, sw, col_shadow, 0, 0, NULL, NULL}, - }; + /* horizontal item line - */ + {true, CC_FBDATA_TYPE_BOX, x, y, width-thickness-sw, thickness, col_body, 0, 0, 0, NULL, NULL, NULL, false}, + {true, CC_FBDATA_TYPE_BOX, x+thickness, y+thickness, width-2*thickness-sw, sw, col_shadow, 0, 0, 0, NULL, NULL, NULL, false}, - for(size_t i =0; i< (sizeof(fbdata) / sizeof(fbdata[0])) ;i++) - v_fbdata.push_back(fbdata[i]); + /* vertical connect line [ */ + {true, CC_FBDATA_TYPE_BOX, x, y+thickness, thickness, y_down-y-thickness, col_body, 0, 0, 0, NULL, NULL, NULL, false}, + {true, CC_FBDATA_TYPE_BOX, x+thickness, y+thickness+sw, sw, y_down-y-thickness-sw, col_shadow, 0, 0, 0, NULL, NULL, NULL, false}, + /* horizontal info line - */ + {true, CC_FBDATA_TYPE_BOX, x, y_down, width-thickness-sw, thickness, col_body, 0, 0, 0, NULL, NULL, NULL, false}, + {true, CC_FBDATA_TYPE_BOX, x+sw, y_down+thickness, width-thickness-2*sw, sw, col_shadow, 0, 0, 0, NULL, NULL, NULL, false}, + + /* vertical info mark | */ + {true, CC_FBDATA_TYPE_BOX, x+width-thickness-sw, y_mark_down, thickness, h_mark_down, col_body, 0, 0, 0, NULL, NULL, NULL, false}, + {true, CC_FBDATA_TYPE_BOX, x+width-sw, y_mark_down+sw, sw, h_mark_down-sw, col_shadow, 0, 0, 0, NULL, NULL, NULL, false}, + {true, CC_FBDATA_TYPE_BOX, x+width-thickness, y_mark_down+h_mark_down,thickness, sw, col_shadow, 0, 0, 0, NULL, NULL, NULL, false}, + }; + + for(size_t i =0; i< (sizeof(fbdata) / sizeof(fbdata[0])) ;i++) + v_fbdata.push_back(fbdata[i]); + } paintFbItems(do_save_bg); } diff --git a/src/gui/components/cc_draw.cpp b/src/gui/components/cc_draw.cpp new file mode 100644 index 000000000..c857d0175 --- /dev/null +++ b/src/gui/components/cc_draw.cpp @@ -0,0 +1,692 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2015, Thilo Graf 'dbt' + Copyright (C) 2012, Michael Liebmann 'micha-bbg' + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include "cc_draw.h" +#include + +#include + +CCDraw::CCDraw() : COSDFader(g_settings.theme.menu_Content_alpha) +{ + frameBuffer = CFrameBuffer::getInstance(); + x = cc_xr = x_old = 0; + y = cc_yr = y_old = 0; + height = height_old = CC_HEIGHT_MIN; + width = width_old = CC_WIDTH_MIN; + + col_body = col_body_old = COL_MENUCONTENT_PLUS_0; + col_shadow = col_shadow_old = COL_MENUCONTENTDARK_PLUS_0; + col_frame = col_frame_old = COL_MENUCONTENT_PLUS_6; + col_frame_sel = col_frame_sel_old = COL_MENUCONTENTSELECTED_PLUS_0; + + fr_thickness = fr_thickness_old = 0; + fr_thickness_sel = fr_thickness_sel_old = 3; + + corner_type = corner_type_old = CORNER_ALL; + corner_rad = corner_rad_old = 0; + + shadow = CC_SHADOW_OFF; + shadow_w = shadow_w_old = SHADOW_OFFSET; + + cc_paint_cache = false; + cc_scrdata.pixbuf = NULL; + cc_save_bg = false; + firstPaint = true; + is_painted = false; + paint_bg = true; + cc_allow_paint = true; + cc_enable_frame = true; + + cc_body_gradient_enable = cc_body_gradient_enable_old = CC_COLGRAD_OFF; + cc_body_gradient_2nd_col = cc_body_gradient_2nd_col_old = COL_MENUCONTENT_PLUS_0; + + cc_body_gradient_mode = CColorGradient::gradientLight2Dark; + cc_body_gradient_intensity = CColorGradient::light; + cc_body_gradient_intensity_v_min = 0x40; + cc_body_gradient_intensity_v_max = 0xE0; + cc_body_gradient_saturation = 0xC0; + cc_body_gradient_direction = cc_body_gradient_direction_old = CFrameBuffer::gradientVertical; + + v_fbdata.clear(); +} + +CCDraw::~CCDraw() +{ + hide(); + clearFbData(); +} + +inline bool CCDraw::applyPosChanges() +{ + bool ret = false; + if (x != x_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], Pos changes x %d != x_old %d...\033[0m\n", __func__, __LINE__, x, x_old); + x_old = x; + ret = true; + } + if (y != y_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], Pos changes y %d != y_old %d...\033[0m\n", __func__, __LINE__, y, y_old); + y_old = y; + ret = true; + } + + return ret; +} + +inline bool CCDraw::applyDimChanges() +{ + bool ret = false; + if (height != height_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], dim changes height %d != height_old %d...\033[0m\n", __func__, __LINE__, height, height_old); + height_old = height; + ret = true; + } + if (width != width_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], dim changes width %d != width_old %d...\033[0m\n", __func__, __LINE__, width, width_old); + width_old = width; + ret = true; + } + if (fr_thickness != fr_thickness_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], dim changes fr_thickness %d != fr_thickness_old %d...\033[0m\n", __func__, __LINE__, fr_thickness, fr_thickness_old); + fr_thickness_old = fr_thickness; + ret = true; + } + if (fr_thickness_sel != fr_thickness_sel_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], dim changes fr_thickness_sel %d != fr_thickness_sel_old %d...\033[0m\n", __func__, __LINE__, fr_thickness_sel, fr_thickness_sel_old); + fr_thickness_old = fr_thickness; + ret = true; + } + if (shadow_w != shadow_w_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], dim changes shadow_w_sel %d != shadow_w_old %d...\033[0m\n", __func__, __LINE__, shadow_w, shadow_w_old); + shadow_w_old = shadow_w; + ret = true; + } + if (corner_rad != corner_rad_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], dim changes corner_rad %d != corner_rad_old %d...\033[0m\n", __func__, __LINE__, corner_rad, corner_rad_old); + corner_rad_old = corner_rad; + ret = true; + } + if (corner_type != corner_type_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], dim changes corner_type %d != corner_type_old %d...\033[0m\n", __func__, __LINE__, corner_type, corner_type_old); + corner_type_old = corner_type; + ret = true; + } + + return ret; +} + +inline bool CCDraw::applyColChanges() +{ + bool ret = false; + if (col_body != col_body_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], col changes col_body %d != col_body_old %d...\033[0m\n", __func__, __LINE__, col_body, col_body_old); + col_body_old = col_body; + ret = true; + } + if (col_shadow != col_shadow_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], col changes col_shadow %d != col_shadow_old %d...\033[0m\n", __func__, __LINE__, col_shadow, col_shadow_old); + col_shadow_old = col_shadow; + ret = true; + } + if (col_frame != col_frame_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], col changes col_frame %d != col_frame_old %d...\033[0m\n", __func__, __LINE__, col_frame, col_frame_old); + col_frame_old = col_frame; + ret = true; + } + if (col_frame_sel != col_frame_sel_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], col changes col_frame_sel %d != col_frame_sel_old %d...\033[0m\n", __func__, __LINE__, col_frame_sel, col_frame_sel_old); + col_frame_old = col_frame; + ret = true; + } + if (cc_body_gradient_enable != cc_body_gradient_enable_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], col changes cc_body_gradient_enable %d != cc_body_gradient_enable_old %d...\033[0m\n", __func__, __LINE__, cc_body_gradient_enable, cc_body_gradient_enable_old); + cc_body_gradient_enable_old = cc_body_gradient_enable; + ret = true; + } + if (cc_body_gradient_2nd_col != cc_body_gradient_2nd_col_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], col changes cc_body_gradient_2nd_col %d != cc_body_gradient_2nd_col_old %d...\033[0m\n", __func__, __LINE__, cc_body_gradient_2nd_col, cc_body_gradient_2nd_col_old); + cc_body_gradient_2nd_col_old = cc_body_gradient_2nd_col; + ret = true; + } + if (cc_body_gradient_direction != cc_body_gradient_direction_old){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], col changes cc_body_gradient_direction %d != cc_body_gradient_direction_old %d...\033[0m\n", __func__, __LINE__, cc_body_gradient_direction, cc_body_gradient_direction_old); + cc_body_gradient_direction_old = cc_body_gradient_direction; + ret = true; + } + + return ret; +} + +inline bool CCDraw::hasChanges() +{ + if (applyPosChanges() || applyDimChanges() || applyColChanges()) + return true; + + return false; +} + +inline void CCDraw::setXPos(const int& xpos) +{ + if (x == xpos) + return; + x = xpos; +} + +inline void CCDraw::setYPos(const int& ypos) +{ + if (y == ypos) + return; + y = ypos; +} + +inline void CCDraw::setHeight(const int& h) +{ + if (height == h) + return; + height = h; +} + +inline void CCDraw::setWidth(const int& w) +{ + if (width == w) + return; + width = w; +} + +void CCDraw::setFrameThickness(const int& thickness, const int& thickness_sel) +{ + fr_thickness = thickness; + + if (fr_thickness_sel != thickness_sel) + fr_thickness_sel = thickness_sel; +} + +bool CCDraw::enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color, const int& direction) +{ + if (cc_body_gradient_enable == enable_mode && cc_body_gradient_direction == direction) + return false; + dprintf(DEBUG_DEBUG, "\033[33m[CCDraw]\t[%s - %d], change gradient mode: current=[%d] new=[%d] direction=[%d]\033[0m\n", __func__, __LINE__, cc_body_gradient_enable, enable_mode, direction); + bool ret = false; + if ((cc_body_gradient_enable != enable_mode) || (cc_body_gradient_enable == CC_COLGRAD_OFF)){ + clearScreenBuffer(); + cc_body_gradient_enable = enable_mode; + ret = true; + } + if (cc_body_gradient_enable == CC_COLGRAD_COL_A_2_COL_B || cc_body_gradient_enable == CC_COLGRAD_COL_B_2_COL_A) + set2ndColor(sec_color); + + //handle direction + if (cc_body_gradient_direction != direction){ + cc_body_gradient_direction = direction; + ret = true; + } + + return ret; +} + +inline void CCDraw::setCornerType(const int& type) +{ + if (corner_type == type) + return; + corner_type = type; +} + +inline void CCDraw::setCorner(const int& radius, const int& type) +{ + setCornerType(type); + if (corner_rad == radius) + return; + corner_rad = radius; +} + +gradientData_t* CCDraw::getGradientData() +{ + if (cc_body_gradient_enable == CC_COLGRAD_OFF) + return NULL; + + gradientData_t* gdata = new gradientData_t; + gdata->gradientBuf = NULL; + gdata->boxBuf = NULL; + gdata->direction = cc_body_gradient_direction; + gdata->mode = CFrameBuffer::pbrg_noFree; + CColorGradient ccGradient; + int gsize = cc_body_gradient_direction == CFrameBuffer::gradientVertical ? height : width; + //TODO: add modes for direction and intensity + switch (cc_body_gradient_enable){ + case CC_COLGRAD_LIGHT_2_DARK: + cc_body_gradient_mode = CColorGradient::gradientLight2Dark; + break; + case CC_COLGRAD_DARK_2_LIGHT: + cc_body_gradient_mode = CColorGradient::gradientDark2Light; + break; + case CC_COLGRAD_COL_A_2_COL_B: + cc_body_gradient_mode = CColorGradient::gradientLight2Dark; + break; + case CC_COLGRAD_COL_B_2_COL_A: + cc_body_gradient_mode = CColorGradient::gradientDark2Light; + break; + case CC_COLGRAD_COL_LIGHT_DARK_LIGHT: + cc_body_gradient_mode = CColorGradient::gradientLight2Dark2Light; + break; + case CC_COLGRAD_COL_DARK_LIGHT_DARK: + cc_body_gradient_mode = CColorGradient::gradientDark2Light2Dark; + break; + } + + if (cc_body_gradient_enable == CC_COLGRAD_COL_A_2_COL_B || cc_body_gradient_enable == CC_COLGRAD_COL_B_2_COL_A){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], init gradient c2c)...\033[0m\n", __func__, __LINE__); + gdata->gradientBuf = ccGradient.gradientColorToColor(col_body, + cc_body_gradient_2nd_col, + NULL, + gsize, + cc_body_gradient_mode, + cc_body_gradient_intensity); + }else{ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], init gradient single color)...\033[0m\n", __func__, __LINE__); + gdata->gradientBuf = ccGradient.gradientOneColor(col_body, + NULL, + gsize, + cc_body_gradient_mode, + cc_body_gradient_intensity, + cc_body_gradient_intensity_v_min, + cc_body_gradient_intensity_v_max, + cc_body_gradient_saturation); + } + + return gdata; +} + +bool CCDraw::clearSavedScreen() +{ + /* Here we clean only screen buffers from background layers. + * Paint cache and gradient are not touched. + */ + bool ret = false; + for(size_t i =0; i< v_fbdata.size() ;i++) { + if (v_fbdata[i].fbdata_type == CC_FBDATA_TYPE_BGSCREEN){ + if (v_fbdata[i].pixbuf){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], cleanup bg...\033[0m\n", __func__, __LINE__); + delete[] v_fbdata[i].pixbuf; + v_fbdata[i].pixbuf = NULL; + ret = true; + } + } + } + return ret; +} + +bool CCDraw::clearPaintCache() +{ + /* Here we clean only the paint cache from foreground layers. + * BG layer is not touched. + */ + bool ret = false; + for(size_t i =0; i< v_fbdata.size() ;i++) { + if (v_fbdata[i].fbdata_type != CC_FBDATA_TYPE_BGSCREEN){ + if (v_fbdata[i].pixbuf){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], cleanup paint cache layer...\033[0m\n", __func__, __LINE__); + delete[] v_fbdata[i].pixbuf; + v_fbdata[i].pixbuf = NULL; + ret = true; + } + } + } + return ret; +} + +//clean old gradient buffer +bool CCDraw::clearFbGradientData() +{ + bool ret = false; + for(size_t i =0; i< v_fbdata.size() ;i++) { + if (v_fbdata[i].gradient_data){ + if (v_fbdata[i].gradient_data->gradientBuf){ + free(v_fbdata[i].gradient_data->gradientBuf); + v_fbdata[i].gradient_data->gradientBuf = NULL; + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], clean up gradientBuf...\033[0m\n", __func__, __LINE__); + } + if (v_fbdata[i].gradient_data->boxBuf){ + cs_free_uncached(v_fbdata[i].gradient_data->boxBuf); + v_fbdata[i].gradient_data->boxBuf = NULL; + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], clean up boxBuf...\033[0m\n", __func__, __LINE__); + } + delete v_fbdata[i].gradient_data; + v_fbdata[i].gradient_data = NULL; + ret = true; + } + } + return ret; +} + +bool CCDraw::clearScreenBuffer() +{ + bool ret = false; + if (clearSavedScreen()) + ret = true; + if (clearPaintCache()) + ret = true; + if (clearFbGradientData()) + ret = true; + firstPaint = true; + return ret; +} + +void CCDraw::clearFbData() +{ + clearScreenBuffer(); + v_fbdata.clear(); +} + +bool CCDraw::CheckFbData(const cc_fbdata_t& fbdata, const char* func, const int line) +{ + int32_t rows = fbdata.dx / (int32_t)frameBuffer->getScreenWidth(true) - 1 + fbdata.y; + int32_t rest = fbdata.dx % (int32_t)frameBuffer->getScreenWidth(true); + int32_t end = rows * (int32_t)frameBuffer->getScreenWidth(true) + rest; + if ( (fbdata.x < 0 || fbdata.y < 0) || + (end >= (int32_t)frameBuffer->getScreenWidth(true)*(int32_t)frameBuffer->getScreenHeight(true)) + ) { + dprintf(DEBUG_NORMAL, "[CCDraw] ERROR! Position < 0 or > FB end [%s - %d]\n\tx = %d y = %d\n\tdx = %d dy = %d\n", + func, line, + fbdata.x, fbdata.y, + fbdata.dx, fbdata.dy); + return false; + } + if (fbdata.dx == 0 || fbdata.dy == 0) { + dprintf(DEBUG_DEBUG,"[CCDraw]\t[%s - %d], INFO! dx and/or dy = 0, tx = %d, y = %d, dx = %d, dy = %d\n", + func, line, + fbdata.x, fbdata.y, + fbdata.dx, fbdata.dy); + return false; + } + return true; +} + + + +//screen area save +fb_pixel_t* CCDraw::getScreen(int ax, int ay, int dx, int dy) +{ + if (dx * dy == 0) + return NULL; + + dprintf(DEBUG_INFO, "[CCDraw] INFO! [%s - %d], ax = %d, ay = %d, dx = %d, dy = %d\n", __func__, __LINE__, ax, ay, dx, dy); + fb_pixel_t* pixbuf = new fb_pixel_t[dx * dy]; + frameBuffer->waitForIdle("CCDraw::getScreen()"); + frameBuffer->SaveScreen(ax, ay, dx, dy, pixbuf); + return pixbuf; +} + +cc_screen_data_t CCDraw::getScreenData(const int& ax, const int& ay, const int& dx, const int& dy) +{ + cc_screen_data_t res; + res.pixbuf = getScreen(ax, ay, dx, dy); + res.x = ax; res.y = ay; res.dx = dx; res.dy = dy; + + return res; +} + +void CCDraw::enableSaveBg(bool save_bg) +{ + if (!cc_save_bg || (cc_save_bg != save_bg)) + clearSavedScreen(); + cc_save_bg = save_bg; +} + +void CCDraw::enablePaintCache(bool enable) +{ + if (!cc_paint_cache || (cc_paint_cache != enable)) + clearPaintCache(); + cc_paint_cache = enable; +} + +//paint framebuffer layers +void CCDraw::paintFbItems(bool do_save_bg) +{ + //first modify background handling + enableSaveBg(do_save_bg); + + //save background before first paint, cc_save_bg must be true + if (firstPaint && cc_save_bg){ + /* On first we must ensure that screen buffer is empty. + * Here we clean possible screen buffers in bg layers, + * without paint cache and gradient buffer. + */ + clearSavedScreen(); + + /* On second step we check for + * usable item dimensions and exit here if found any problem + */ + for(size_t i=0; isave screen: %d, fbdata_type: %d\n\tx = %d\n\ty = %d\n\tdx = %d\n\tdy = %d\n", + __func__, + __LINE__, + firstPaint, + v_fbdata[i].fbdata_type, + v_fbdata[i].x, + v_fbdata[i].y, + v_fbdata[i].dx, + v_fbdata[i].dy); + + /* here we save the background of current box before paint. + * Only the reserved fbdata type CC_FBDATA_TYPE_BGSCREEN is here required and is used for this. + * This pixel buffer is required for the hide() method that will + * call the restore method from framebuffer class to restore + * background. + */ + if (v_fbdata[i].fbdata_type == CC_FBDATA_TYPE_BGSCREEN){ + v_fbdata[i].pixbuf = getScreen(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy); + break; + } + } + firstPaint = false; + } + + for(size_t i=0; i< v_fbdata.size(); i++){ + cc_fbdata_t& fbdata = v_fbdata[i]; + + // Don't paint on dimension or position error dx or dy are 0 + if (!CheckFbData(fbdata, __func__, __LINE__)){ + continue; + } + int fbtype = fbdata.fbdata_type; + + dprintf(DEBUG_DEBUG, "[CCDraw]\n\t[%s - %d], fbdata_[%d]\n\tx = %d\n\ty = %d\n\tdx = %d\n\tdy = %d\n", + __func__, + __LINE__, + (int)i, + fbdata.x, + fbdata.y, + fbdata.dx, + fbdata.dy); + + /*paint all fb relevant basic parts (shadow, frame and body) + * with all specified properties, paint_bg must be enabled + */ + if (cc_enable_frame){ + if (fbtype == CC_FBDATA_TYPE_FRAME) { + if (fbdata.frame_thickness > 0 && cc_allow_paint) + frameBuffer->paintBoxFrame(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.frame_thickness, fbdata.color, fbdata.r, fbdata.rtype); + } + } + if (paint_bg){ + if (fbtype == CC_FBDATA_TYPE_BACKGROUND){ + frameBuffer->paintBackgroundBoxRel(x, y, fbdata.dx, fbdata.dy); + } + else if (fbtype == CC_FBDATA_TYPE_SHADOW_BOX && !is_painted) { //TODO: is_painted is too global here, shadow will not paint on current instance without called kill/hide + if (fbdata.enabled) { + /* here we paint the shadow around the body + * on 1st step we check for already cached screen buffer, if true + * then restore this instead to call the paint methode. + * This could be usally, if we use existant instances of "this" object + */ + if (cc_allow_paint){ + if (fbdata.pixbuf){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], paint shadow from cache...\033[0m\n", __func__, __LINE__); + frameBuffer->RestoreScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.pixbuf); + }else{ + frameBuffer->paintBoxRel(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.color, fbdata.r, fbdata.rtype); + } + //if is paint cache enabled + if (cc_paint_cache && fbdata.pixbuf == NULL) + fbdata.pixbuf = getScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy); + } + } + } + else if (fbtype == CC_FBDATA_TYPE_BOX){ + if(cc_allow_paint) { + /* here we paint the main body of box + * on 1st step we check for already cached background buffer, if true + * then restore this instead to call the paint methodes and gradient creation + * paint cache can be enable/disable with enablePaintCache() + */ + if (fbdata.pixbuf){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], paint body from cache...\033[0m\n", __func__, __LINE__); + frameBuffer->RestoreScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.pixbuf); + }else{ + //ensure clean gradient data on disabled gradient + if(cc_body_gradient_enable == CC_COLGRAD_OFF && fbdata.gradient_data){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], gradient mode is disabled but filled\033[0m\n", __func__, __LINE__); + clearFbGradientData(); + } + if (cc_body_gradient_enable != CC_COLGRAD_OFF){ + /* if color gradient enabled we create a gradient_data + * instance and add it to the fbdata object + * On disabled coloor gradient we do paint only a default box + */ + if (fbdata.gradient_data == NULL){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], crate new gradient data)...\033[0m\n", __func__, __LINE__); + fbdata.gradient_data = getGradientData(); + } + + // if found empty gradient buffer, create it, otherwise paint from cache + if (fbdata.gradient_data->boxBuf == NULL){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], paint new gradient)...\033[0m\n", __func__, __LINE__); + fbdata.gradient_data->boxBuf = frameBuffer->paintBoxRel(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, 0, fbdata.gradient_data, fbdata.r, fbdata.rtype); + if (cc_paint_cache) + fbdata.pixbuf = getScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy); + }else{ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], paint cached gradient)...\033[0m\n", __func__, __LINE__); + frameBuffer->blitBox2FB(fbdata.gradient_data->boxBuf, fbdata.dx, fbdata.dy, fbdata.x, fbdata.y); + } + }else{ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], paint default box)...\033[0m\n", __func__, __LINE__); + frameBuffer->paintBoxRel(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.color, fbdata.r, fbdata.rtype); + if (cc_paint_cache) + fbdata.pixbuf = getScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy); + } + } + is_painted = true; + } + } + } + } +} + + + +void CCDraw::hide() +{ + bool restored = false; + + //restore saved screen background of item if available + for(size_t i =0; i< v_fbdata.size() ;i++) { + if (v_fbdata[i].fbdata_type == CC_FBDATA_TYPE_BGSCREEN){ + if (v_fbdata[i].pixbuf) { + //restore screen from backround layer + frameBuffer->waitForIdle("CCDraw::hide()"); + frameBuffer->RestoreScreen(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy, v_fbdata[i].pixbuf); + restored = true; + } + } + } + //cleanup background layer, but only if restore was required + if (restored) + clearSavedScreen(); + + is_painted = false; + firstPaint = true; +} + +//erase or paint over rendered objects +void CCDraw::kill(const fb_pixel_t& bg_color, const int& corner_radius) +{ + for(size_t i =0; i< v_fbdata.size() ;i++){ +#if 0 + if (bg_color != COL_BACKGROUND_PLUS_0) +#endif + int r = v_fbdata[i].r; + if (corner_radius > -1) + r = corner_radius; + frameBuffer->paintBoxRel(v_fbdata[i].x, + v_fbdata[i].y, + v_fbdata[i].dx, + v_fbdata[i].dy, + bg_color, + r, + corner_type); + if (v_fbdata[i].frame_thickness) + frameBuffer->paintBoxFrame(v_fbdata[i].x, + v_fbdata[i].y, + v_fbdata[i].dx, + v_fbdata[i].dy, + v_fbdata[i].frame_thickness, + bg_color, + r, + corner_type); + +#if 0 + else + frameBuffer->paintBackgroundBoxRel(v_fbdata[i].x, v_fbdata[i].y, v_fbdata[i].dx, v_fbdata[i].dy); +#endif + } + + firstPaint = true; + is_painted = false; +} + +bool CCDraw::doPaintBg(bool do_paint) +{ + if (paint_bg == do_paint) + return false; + + paint_bg = do_paint; + //clearSavedScreen(); + return true; +} + +void CCDraw::enableShadow(int mode, const int& shadow_width) +{ + if (shadow != mode) + shadow = mode; + if (shadow != CC_SHADOW_OFF) + if (shadow_width != -1) + setShadowWidth(shadow_width); +} + diff --git a/src/gui/components/cc_draw.h b/src/gui/components/cc_draw.h new file mode 100644 index 000000000..989a2ee5f --- /dev/null +++ b/src/gui/components/cc_draw.h @@ -0,0 +1,309 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2015, Thilo Graf 'dbt' + Copyright (C) 2012, Michael Liebmann 'micha-bbg' + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __CC_DRAW__ +#define __CC_DRAW__ + +#include "cc_types.h" +#include +#include +#include + +/// Basic component class. +/*! +Basic paint attributes and member functions for component classes +*/ + +class CCDraw : public COSDFader +{ + protected: + ///pixel buffer handling, returns pixel buffer depends of given parameters + fb_pixel_t* getScreen(int ax, int ay, int dx, int dy); + ///returns screen data as screen_data_t + cc_screen_data_t getScreenData(const int& ax, const int& ay, const int& dx, const int& dy); + cc_screen_data_t cc_scrdata; + + ///object: framebuffer object, usable in all sub classes + CFrameBuffer * frameBuffer; + + ///property: x-position on screen, to alter with setPos() or setDimensionsAll(), see also defines CC_APPEND, CC_CENTERED + int x, x_old; + ///property: y-position on screen, to alter setPos() or setDimensionsAll(), see also defines CC_APPEND, CC_CENTERED + int y, y_old; + ///property: contains real x-position on screen + int cc_xr; + ///property: contains real y-position on screen + int cc_yr; + ///property: height-dimension on screen, to alter with setHeight() or setDimensionsAll() + int height, height_old; + ///property: width-dimension on screen, to alter with setWidth() or setDimensionsAll() + int width, width_old; + + ///property: color of body + fb_pixel_t col_body, col_body_old; + ///property: color of shadow + fb_pixel_t col_shadow, col_shadow_old; + ///property: color of frame + fb_pixel_t col_frame, col_frame_old; + ///property: color of frame if component is selected, Note: fr_thickness_sel must be set + fb_pixel_t col_frame_sel, col_frame_sel_old; + + ///property: frame thickness, see also setFrameThickness() + int fr_thickness, fr_thickness_old; + ///property: frame thickness of selected component, see also setFrameThickness() + int fr_thickness_sel, fr_thickness_sel_old; + + ///property: has corners with definied type, types are defined in /driver/frambuffer.h, without effect, if corner_radius=0 + int corner_type, corner_type_old; + ///property: defined radius of corner, without effect, if corner_type=0 + int corner_rad, corner_rad_old; + + ///property: shadow mode 0 = CC_SHADOW_OFF + int shadow; + ///property: width of shadow + int shadow_w, shadow_w_old; + + ///returns true if internal property was changed + virtual bool hasChanges(); + ///apply current position changes and returns true if internal values were changed + virtual bool applyPosChanges(); + ///apply current dimension changes and returns true if internal values were changed + virtual bool applyDimChanges(); + ///apply current color changes and returns true if internal values were changed + virtual bool applyColChanges(); + + ///paint caching for body and shadow, default init value = true, see also enablePaintCache() NOTE: has no effect if paint_bg = false + bool cc_paint_cache; + + ///enable/disable background buffer, default init value = false, see also enableSaveBg() + bool cc_save_bg; + + ///container: for frambuffer properties and pixel buffer + std::vector v_fbdata; + + ///status: true=component was painted for 1st time + bool firstPaint; + ///status: true=component was rendered + bool is_painted; + ///mode: true=activate rendering of basic elements (frame, shadow and body) + bool paint_bg; + ///mode: true=activate rendering of frame + bool cc_enable_frame; + ///mode: true=allows painting of item, see also allowPaint() + bool cc_allow_paint; + + ///property: true component can paint gradient, see also enableColBodyGradient() TODO: if possible, merge all gradient properties into only one variable + int cc_body_gradient_enable, cc_body_gradient_enable_old; + ///property: background gradient mode + int cc_body_gradient_mode; + ///property: background gradient intensity + int cc_body_gradient_intensity; + ///property: background gradient intensity value min + uint8_t cc_body_gradient_intensity_v_min; + ///property: background gradient intensity value max + uint8_t cc_body_gradient_intensity_v_max; + ///property: background gradient saturation + uint8_t cc_body_gradient_saturation; + ///property: background gradient direction + int cc_body_gradient_direction, cc_body_gradient_direction_old; + + //TODO: move into layers + int old_gradient_color; + ///property: background gradient 2nd color + fb_pixel_t cc_body_gradient_2nd_col, cc_body_gradient_2nd_col_old; + + ///check current fbdtata position and dimensions, parameter fbdata is an element of v_fbdata, returns false on error + bool CheckFbData(const cc_fbdata_t& fbdata, const char* func, const int line); + + ///sub: get gradient data evaluted with current parameters + gradientData_t* getGradientData(); + + ///rendering of framebuffer elements at once, + ///elements are contained in v_fbdata, presumes added frambuffer elements with paintInit(), + ///parameter do_save_bg=true, saves background of element to pixel buffer, this can be restore with hide() + void paintFbItems(bool do_save_bg = true); + + public: + ///basic component class constructor. + CCDraw(); + virtual~CCDraw(); + + ///cleans saved screen buffer, required by hide(), returns true if any buffer was deleted + virtual bool clearSavedScreen(); + ///cleanup paint cache, removes saved buffer contents from cached foreground layers, returns true if any buffer was removed + virtual bool clearPaintCache(); + ///cleanup old gradient buffers, returns true if any gradient buffer data was removed + virtual bool clearFbGradientData(); + + ///cleans all possible screen buffers, it calls clearSavedScreen(), clearPaintCache() and clearFbGradientData() at once + virtual bool clearScreenBuffer(); + ///does the same like clearScreenBuffer(), additional cleans v_fbdata layers and reset layer properties + virtual void clearFbData(); + + ///set screen x-position, parameter as int + virtual void setXPos(const int& xpos); + ///set screen y-position, parameter as int + virtual void setYPos(const int& ypos); + ///set x and y position at once + ///Note: position of bound components (items) means position related within parent form, not for screen! + ///to set the real screen position, look at setRealPos() + virtual void setPos(const int& xpos, const int& ypos){setXPos(xpos); setYPos(ypos);} + + ///sets real x position on screen. Use this, if item is added to a parent form + virtual void setRealXPos(const int& xr){cc_xr = xr;} + ///sets real y position on screen. Use this, if item is added to a parent form + virtual void setRealYPos(const int& yr){cc_yr = yr;} + ///sets real x and y position on screen at once. Use this, if item is added to a parent form + virtual void setRealPos(const int& xr, const int& yr){cc_xr = xr; cc_yr = yr;} + ///get real x-position on screen. Use this, if item contains own render methods and item is bound to a form + virtual int getRealXPos(){return cc_xr;} + ///get real y-position on screen. Use this, if item contains own render methods and item is bound to a form + virtual int getRealYPos(){return cc_yr;} + + ///set height of component on screen + virtual void setHeight(const int& h); + ///set width of component on screen + virtual void setWidth(const int& w); + ///set all positions and dimensions of component at once + virtual void setDimensionsAll(const int& xpos, const int& ypos, const int& w, const int& h){setPos(xpos, ypos); setWidth(w); setHeight(h);} + + ///return screen x-position of component + ///Note: position of bound components (items) means position related within parent form, not for screen! + ///to get the real screen position, use getRealXPos(), to find in CComponentsItem sub classes + virtual int getXPos(){return x;}; + ///return screen y-position of component + ///Note: position of bound components (items) means position related within parent form, not for screen! + ///to get the real screen position, use getRealYPos(), to find in CComponentsItem sub classes + virtual int getYPos(){return y;} + ///return height of component + virtual int getHeight(){return height;} + ///return width of component + virtual int getWidth(){return width;} + + ///return/set (pass through) width and height of component + virtual void getSize(int* w, int* h){*w=width; *h=height;} + ///return/set (pass through) position and dimensions of component at once + virtual void getDimensions(int* xpos, int* ypos, int* w, int* h){*xpos=x; *ypos=y; *w=width; *h=height;} + + ///set frame thickness + virtual void setFrameThickness(const int& thickness, const int& thickness_sel = 3); + ///return of frame thickness + virtual int getFrameThickness(){return fr_thickness;} + ///set frame color + virtual void setColorFrame(fb_pixel_t color){col_frame = color;} + ///set selected frame color + virtual void setColorFrameSel(fb_pixel_t color){col_frame_sel = color;} + virtual void set2ndColor(fb_pixel_t col_2nd){cc_body_gradient_2nd_col = col_2nd;} + + ///get frame color + virtual fb_pixel_t getColorFrame(){return col_frame;} + ///get body color + virtual fb_pixel_t getColorBody(){return col_body;} + ///get shadow color + virtual fb_pixel_t getColorShadow(){return col_shadow;} + + ///set body color + virtual void setColorBody(fb_pixel_t color){col_body = color;} + ///set shadow color + virtual void setColorShadow(fb_pixel_t color){col_shadow = color;} + ///set all basic framebuffer element colors at once + ///Note: Possible color values are defined in "gui/color.h" and "gui/customcolor.h" + virtual void setColorAll(fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow){col_frame = color_frame; col_body = color_body; col_shadow = color_shadow;}; + + ///set corner types + ///Possible corner types are defined in CFrameBuffer (see: driver/framebuffer.h) + ///Note: default values are given from settings + virtual void setCornerType(const int& type); + ///set corner radius and type + virtual void setCorner(const int& radius, const int& type = CORNER_ALL); + ///get corner types + inline virtual int getCornerType(){return corner_type;}; + ///get corner radius + inline virtual int getCornerRadius(){return corner_rad;}; + + ///switch shadow on/off + virtual void setShadowWidth(const int& shadow_width){if (shadow_w != shadow_width) shadow_w = shadow_width;} + ///Note: it's recommended to use #defines: CC_SHADOW_ON=true or CC_SHADOW_OFF=false as parameter, see also cc_types.h + virtual void enableShadow(int mode = CC_SHADOW_ON, const int& shadow_width = -1); + ///switch shadow off + virtual void disableShadow(){enableShadow(CC_SHADOW_OFF);} + + ///paint caching for body and shadow, see also cc_paint_cache NOTE: has no effect if paint_bg = false + virtual void enablePaintCache(bool enable = true); + ///disable paint caching for body and shadow + virtual void disablePaintCache(){enablePaintCache(false);} + + ///returns paint mode, true=item was painted + virtual bool isPainted(){return is_painted;} + ///allows paint of elementary item parts (shadow, frame and body), similar as background, set it usually to false, if item used in a form, returns true, if mode has changed, also cleans screnn buffer + virtual bool doPaintBg(bool do_paint); + ///allows paint frame around body, default true , NOTE: ignored if frame width = 0 + virtual void enableFrame(bool enable = true, const int& frame_width = -1){cc_enable_frame = enable; setFrameThickness(frame_width == -1 ? fr_thickness : frame_width);} + ///disallow paint frame around body + virtual void disableFrame(){enableFrame(false);} + ///enable/disable background buffering, default action = enable, see also cc_save_bg + virtual void enableSaveBg(bool save_bg = true); + ///disable background buffering, does the same like enableSaveBg(false), NOTE: cleans existant pixbuffer content! + virtual void disableSaveBg(){enableSaveBg(false);} + + ///allow/disalows paint of item and its contents, but initialize of other properties are not touched + ///this can be understood as a counterpart to isPainted(), but before paint and value of is_painted is modified temporarily till next paint of item //TODO: is this sufficiently? + void allowPaint(bool allow){cc_allow_paint = allow; is_painted = cc_allow_paint ? false : true;} + ///returns visibility mode + virtual bool paintAllowed(){return cc_allow_paint;}; + + ///set color gradient on/off, returns true if gradient mode was changed + virtual bool enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color = 255 /*=COL_BACKGROUND*/, const int& direction = 1 /*CFrameBuffer::gradientVertical*/); + ///disable color gradient, returns true if gradient mode was changed + virtual bool disableColBodyGradient(){return enableColBodyGradient(CC_COLGRAD_OFF);} + ///set color gradient properties, possible parameter values for mode and intensity to find in CColorGradient, in driver/framebuffer.h> + virtual void setColBodyGradient(const int& mode, const int& direction = 1 /*CFrameBuffer::gradientVertical*/, const fb_pixel_t& sec_color = 255 /*=COL_BACKGROUND*/, const int& intensity = CColorGradient::normal, uint8_t v_min=0x40, uint8_t v_max=0xE0, uint8_t s=0xC0) + { cc_body_gradient_intensity=intensity; + cc_body_gradient_intensity_v_min=v_min; + cc_body_gradient_intensity_v_max=v_max; + cc_body_gradient_saturation=s; + enableColBodyGradient(mode, sec_color, direction);} + ///gets current color gradient mode + virtual int getColBodyGradientMode(){return cc_body_gradient_enable;} + + ///abstract: paint item, arg: do_save_bg see paintInit() above + virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES) = 0; + ///paint item, same like paint(CC_SAVE_SCREEN_YES) but without any argument + virtual void paint1(){paint(CC_SAVE_SCREEN_YES);} + ///paint item, same like paint(CC_SAVE_SCREEN_NO) but without any argument + virtual void paint0(){paint(CC_SAVE_SCREEN_NO);} + + /*! + Removes current item from screen and + restore last displayed background before item was painted and + ensures demage of already existing screen buffers too. + */ + virtual void hide(); + + ///erase or paint over rendered objects without restore of background, it's similar to paintBackgroundBoxRel() known + ///from CFrameBuffer but with possiblity to define color, default color is COL_BACKGROUND_PLUS_0 (empty background) + virtual void kill(const fb_pixel_t& bg_color = COL_BACKGROUND_PLUS_0, const int& corner_radius = -1); +}; + +#endif diff --git a/src/gui/components/cc_extra.cpp b/src/gui/components/cc_extra.cpp new file mode 100644 index 000000000..00d3a8310 --- /dev/null +++ b/src/gui/components/cc_extra.cpp @@ -0,0 +1,123 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Extra functions based up GUI-related components. + Copyright (C) 2015, Thilo Graf 'dbt' + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include "cc_extra.h" +#include + +using namespace std; + +bool paintBoxRel( const int& x, + const int& y, + const int& dx, + const int& dy, + const fb_pixel_t& color_body, + const int& radius, + const int& corner_type, + const int& gradient_mode, + const int& gradient_sec_col, + const int& gradient_direction, + const int& gradient_intensity, + const int& w_frame, + const fb_pixel_t& color_frame, + int shadow_mode, + const fb_pixel_t& color_shadow) +{ + CComponentsShapeSquare box(x, y, dx, dy, NULL, shadow_mode, color_frame, color_body, color_shadow); + box.setColBodyGradient(gradient_mode, gradient_direction, gradient_sec_col, gradient_intensity); + box.setCorner(radius, corner_type); + box.enableFrame(w_frame, w_frame); + box.paint(CC_SAVE_SCREEN_NO); + return box.isPainted(); +} + +bool paintBoxRel0( const int& x, + const int& y, + const int& dx, + const int& dy, + const fb_pixel_t& color_body, + const int& radius, + const int& corner_type, + const int& w_frame, + const fb_pixel_t& color_frame, + int shadow_mode, + const fb_pixel_t& color_shadow) +{ + return paintBoxRel(x, y, dx, dy, color_body, radius, corner_type, w_frame, CC_COLGRAD_OFF, COL_MENUCONTENT_PLUS_0, CFrameBuffer::gradientVertical, CColorGradient::normal, color_frame, shadow_mode, color_shadow); +} + +bool paintTextBoxRel( const string& text, + const int& x, + const int& y, + const int& dx, + const int& dy, + Font *font, + const int& mode, + const int& font_style, + const fb_pixel_t& color_text, + const fb_pixel_t& color_body, + const int& radius, + const int& corner_type, + const int& gradient_mode, + const int& gradient_sec_col, + const int& gradient_direction, + const int& gradient_intensity, + const fb_pixel_t& color_frame, + int shadow_mode, + const fb_pixel_t& color_shadow) +{ + CComponentsText box(x, y, dx, dy, text, mode, font, font_style, NULL, shadow_mode, color_text, color_frame, color_body, color_shadow); + box.setColBodyGradient(gradient_mode, gradient_direction, gradient_sec_col, gradient_intensity); + box.doPaintBg(color_body !=0); + box.enableTboxSaveScreen(false); + box.setCorner(radius, corner_type); + box.paint(CC_SAVE_SCREEN_NO); + + return box.isPainted(); +} + +bool paintImage( const std::string& image_name, + const int& x, + const int& y, + const int& dx, + const int& dy, + const int& transparent, + const fb_pixel_t& color_body, + const int& radius, + const int& corner_type, + const fb_pixel_t& color_frame, + int shadow_mode, + const fb_pixel_t& color_shadow) +{ + CComponentsPicture box( x, y, dx, dy, image_name, NULL, shadow_mode, color_frame, color_body, color_shadow, transparent); + box.doPaintBg(color_body !=0); + box.setCorner(radius, corner_type); + box.paint(CC_SAVE_SCREEN_NO); + + return box.isPicPainted(); +} diff --git a/src/gui/components/cc_extra.h b/src/gui/components/cc_extra.h new file mode 100644 index 000000000..f63b75a75 --- /dev/null +++ b/src/gui/components/cc_extra.h @@ -0,0 +1,276 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Extra functions based up GUI-related components. + Copyright (C) 2015, Thilo Graf 'dbt' + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __CC_EXTRA_H__ +#define __CC_EXTRA_H__ + +#include "cc_item_shapes.h" +#include "cc_item_text.h" + +/** Paint a box on screen. +* @param[in] x position +* @param[in] y position +* @param[in] dx witdh +* @param[in] dy height +* @param[in] color_body color of background, default = COL_MENUCONTENT_PLUS_0 +* @param[in] radius corner radius, default = 0 +* @param[in] corner_type corner type, defined in drivers/framebuffer.h +* @li CORNER_NONE (default) +* @li CORNER_TOP_LEFT +* @li CORNER_TOP_RIGHT +* @li CORNER_TOP +* @li CORNER_BOTTOM_RIGHT +* @li CORNER_RIGHT +* @li CORNER_BOTTOM_LEFT +* @li CORNER_LEFT +* @li CORNER_BOTTOM +* @li CORNER_ALL +* @param[in] gradient_mode mode of color gradient +* @li CC_COLGRAD_OFF (default) +* @li CC_COLGRAD_LIGHT_2_DARK +* @li CC_COLGRAD_DARK_2_LIGHT +* @li CC_COLGRAD_COL_A_2_COL_B +* @li CC_COLGRAD_COL_B_2_COL_A +* @li CC_COLGRAD_COL_LIGHT_DARK_LIGHT +* @li CC_COLGRAD_COL_DARK_LIGHT_DARK +* @param[in] gradient_sec_col secondary gradient color, default = COL_MENUCONTENT_PLUS_0 +* @param[in] gradient_direction mode of color gradient +* @li CFrameBuffer::gradientVertical (default) +* @li CFrameBuffer::gradientHorizontal +* @param[in] gradient_intensity gradient intensity +* @li ColorGradient::light +* @li ColorGradient::normal (default) +* @li CFrameBuffer::advanced +* @param[in] color_frame color of frame around box, default = COL_MENUCONTENT_PLUS_6 +* @param[in] shadow_mode enable/disable shadow behind box, default = CC_SHADOW_OFF +* @param[in] color_shadow color of shadow, default = COL_MENUCONTENTDARK_PLUS_0 +* +* @return +* True if painted +* @see +* @li CCDraw() +* @li CComponentsShapeSquare() +* @li colors.h +* @li driver/framebuffer.h +* @li driver/colorgradient.h +*/ +bool paintBoxRel( const int& x, + const int& y, + const int& dx, + const int& dy, + const fb_pixel_t& color_body = COL_MENUCONTENT_PLUS_0, + const int& radius = 0, + const int& corner_type = CORNER_NONE, + const int& gradient_mode = CC_COLGRAD_OFF, + const int& gradient_sec_col = COL_MENUCONTENT_PLUS_0, + const int& gradient_direction = CFrameBuffer::gradientVertical, + const int& gradient_intensity = CColorGradient::normal, + const int& w_frame = 0, + const fb_pixel_t& color_frame = COL_MENUCONTENT_PLUS_6, + int shadow_mode = CC_SHADOW_OFF, + const fb_pixel_t& color_shadow = COL_MENUCONTENTDARK_PLUS_0); + +/** Paint a box on screen. +* @param[in] x position +* @param[in] y position +* @param[in] dx witdh +* @param[in] dy height +* @param[in] color_body color of background, default = COL_MENUCONTENT_PLUS_0 +* @param[in] radius corner radius, default = 0 +* @param[in] corner_type corner type, defined in drivers/framebuffer.h +* @li CORNER_NONE (default) +* @li CORNER_TOP_LEFT +* @li CORNER_TOP_RIGHT +* @li CORNER_TOP +* @li CORNER_BOTTOM_RIGHT +* @li CORNER_RIGHT +* @li CORNER_BOTTOM_LEFT +* @li CORNER_LEFT +* @li CORNER_BOTTOM +* @li CORNER_ALL +* @param[in] color_frame color of frame around box, default = COL_MENUCONTENT_PLUS_6 +* @param[in] shadow_mode enable/disable shadow behind box, default = CC_SHADOW_OFF +* @param[in] color_shadow color of shadow, default = COL_MENUCONTENTDARK_PLUS_0 +* +* @return +* True if painted +* @see +* @li CCDraw() +* @li CComponentsShapeSquare() +* @li colors.h +* @li driver/framebuffer.h +* @li driver/colorgradient.h +*/ +bool paintBoxRel0( const int& x, + const int& y, + const int& dx, + const int& dy, + const fb_pixel_t& color_body, + const int& radius = 0, + const int& corner_type = CORNER_NONE, + const int& w_frame = 0, + const fb_pixel_t& color_frame = COL_MENUCONTENT_PLUS_6, + int shadow_mode = CC_SHADOW_OFF, + const fb_pixel_t& color_shadow = COL_MENUCONTENTDARK_PLUS_0); + +/** Paint a text box on screen. +* @param[in] std::string& text +* @param[in] x position +* @param[in] y position +* @param[in] dx witdh +* @param[in] dy height +* @param[in] *font pointer to font type object, default = NULL, sets g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL] as default font +* @param[in] color_body color of box, default = COL_MENUCONTENT_PLUS_0 +* @param[in] font_style font style +* @li CComponentsText::FONT_STYLE_REGULAR (default) +* @li CComponentsText::FONT_STYLE_BOLD, +* @li CComponentsText::FONT_STYLE_ITALIC +* @param[in] radius corner radius, default = 0 +* @param[in] corner_type corner type, defined in drivers/framebuffer.h +* @li CORNER_NONE (default) +* @li CORNER_TOP_LEFT +* @li CORNER_TOP_RIGHT +* @li CORNER_TOP +* @li CORNER_BOTTOM_RIGHT +* @li CORNER_RIGHT +* @li CORNER_BOTTOM_LEFT +* @li CORNER_LEFT +* @li CORNER_BOTTOM +* @li CORNER_ALL +* @param[in] gradient_mode mode of color gradient +* @li CC_COLGRAD_OFF (default) +* @li CC_COLGRAD_LIGHT_2_DARK +* @li CC_COLGRAD_DARK_2_LIGHT +* @li CC_COLGRAD_COL_A_2_COL_B +* @li CC_COLGRAD_COL_B_2_COL_A +* @li CC_COLGRAD_COL_LIGHT_DARK_LIGHT +* @li CC_COLGRAD_COL_DARK_LIGHT_DARK +* @param[in] gradient_sec_col secondary gradient color, default = COL_MENUCONTENT_PLUS_0 +* @param[in] gradient_direction mode of color gradient +* @li CFrameBuffer::gradientVertical (default) +* @li CFrameBuffer::gradientHorizontal +* @param[in] gradient_intensity gradient intensity +* @li ColorGradient::light +* @li ColorGradient::normal (default) +* @li CFrameBuffer::advanced +* @param[in] color_frame color of frame around box, default = COL_MENUCONTENT_PLUS_6 +* @param[in] shadow_mode enable/disable shadow behind box, default = CC_SHADOW_OFF +* @param[in] color_shadow color of shadow, default = COL_MENUCONTENTDARK_PLUS_0 +* +* @return +* True if painted +* @see +* @li CCDraw() +* @li CComponentsText() +* @li CComponentsLabel() +* @li CTextBox() +* @li colors.h +* @li driver/framebuffer.h +* @li driver/colorgradient.h +*/ +bool paintTextBoxRel( const std::string& text, + const int& x, + const int& y, + const int& dx, + const int& dy = 0, + Font *font = NULL, + const int& mode = CTextBox::AUTO_WIDTH, + const int& font_style = CComponentsText::FONT_STYLE_REGULAR, + const fb_pixel_t& color_text = COL_MENUCONTENT_TEXT, + const fb_pixel_t& color_body = COL_MENUCONTENT_PLUS_0, + const int& radius = 0, + const int& corner_type = CORNER_NONE, + const int& gradient_mode = CC_COLGRAD_OFF, + const int& gradient_sec_col = COL_MENUCONTENT_PLUS_0, + const int& gradient_direction = CFrameBuffer::gradientVertical, + const int& gradient_intensity = CColorGradient::normal, + const fb_pixel_t& color_frame = COL_MENUCONTENT_PLUS_6, + int shadow_mode = CC_SHADOW_OFF, + const fb_pixel_t& color_shadow = COL_MENUCONTENTDARK_PLUS_0); + +/** Paint an image on screen. +* @param[in] std::string& full path or filename +* @param[in] x position +* @param[in] y position +* @param[in] dx witdh, default = 0 (no scale) +* @param[in] dy height, default = 0 (no scale) +* @param[in] transparent image transparency mode +* @li CFrameBuffer::TM_EMPTY + @li CFrameBuffer::TM_NONE (default) + @li CFrameBuffer::TM_BLACK + @li CFrameBuffer::TM_INI +* @param[in] color_body color of background, default = 0 (no background) +* @param[in] radius corner radius of background, default = 0 +* @param[in] corner_type corner type of background, defined in drivers/framebuffer.h +* @li CORNER_NONE (default) +* @li CORNER_TOP_LEFT +* @li CORNER_TOP_RIGHT +* @li CORNER_TOP +* @li CORNER_BOTTOM_RIGHT +* @li CORNER_RIGHT +* @li CORNER_BOTTOM_LEFT +* @li CORNER_LEFT +* @li CORNER_BOTTOM +* @li CORNER_ALL +* @param[in] gradient_mode mode of background color gradient +* @li CC_COLGRAD_OFF (default) +* @li CC_COLGRAD_LIGHT_2_DARK +* @li CC_COLGRAD_DARK_2_LIGHT +* @li CC_COLGRAD_COL_A_2_COL_B +* @li CC_COLGRAD_COL_B_2_COL_A +* @li CC_COLGRAD_COL_LIGHT_DARK_LIGHT +* @li CC_COLGRAD_COL_DARK_LIGHT_DARK +* @param[in] gradient_sec_col secondary gradient background color, default = COL_MENUCONTENT_PLUS_0 +* @param[in] gradient_direction background color gradient direction +* @li CFrameBuffer::gradientVertical (default) +* @li CFrameBuffer::gradientHorizontal +* @param[in] gradient_intensity background gradient intensity +* @li ColorGradient::light +* @li ColorGradient::normal (default) +* @li CFrameBuffer::advanced +* @param[in] color_frame color of frame around box, default = COL_MENUCONTENT_PLUS_6 +* @param[in] shadow_mode enable/disable shadow behind box, default = CC_SHADOW_OFF +* @param[in] color_shadow color of shadow, default = COL_MENUCONTENTDARK_PLUS_0 +* +* @return +* True if painted +* @see +* @li icons.h +* @li colors.h +* @li CComponentsPicture() +* @li driver/framebuffer.h +* @li driver/colorgradient.h +*/ +bool paintImage( const std::string& image_name, + const int& x, + const int& y, + const int& dx = 0, + const int& dy = 0, + const int& transparent = CFrameBuffer::TM_NONE, + const fb_pixel_t& color_body = 0, + const int& radius = 0, + const int& corner_type = CORNER_NONE, + const fb_pixel_t& color_frame = COL_MENUCONTENT_PLUS_6, + int shadow_mode = CC_SHADOW_OFF, + const fb_pixel_t& color_shadow = COL_MENUCONTENTDARK_PLUS_0); +#endif diff --git a/src/gui/components/cc_frm.cpp b/src/gui/components/cc_frm.cpp index 69fa66b3c..3b61a8023 100644 --- a/src/gui/components/cc_frm.cpp +++ b/src/gui/components/cc_frm.cpp @@ -39,7 +39,7 @@ using namespace std; //sub class CComponentsForm from CComponentsItem CComponentsForm::CComponentsForm( const int x_pos, const int y_pos, const int w, const int h, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) @@ -47,18 +47,11 @@ CComponentsForm::CComponentsForm( const int x_pos, const int y_pos, const int w, { cc_item_type = CC_ITEMTYPE_FRM; - x = x_pos; - y = y_pos; - cc_xr = x; - cc_yr = y; - width = w; - height = h; - - shadow = has_shadow; - col_frame = color_frame; - col_body = color_body; - col_shadow = color_shadow; + Init(x_pos, y_pos, w, h, color_frame, color_body, color_shadow); + cc_xr = x; + cc_yr = y; + shadow = shadow_mode; shadow_w = SHADOW_OFFSET; corner_rad = RADIUS_LARGE; corner_type = CORNER_ALL; @@ -80,6 +73,15 @@ CComponentsForm::CComponentsForm( const int x_pos, const int y_pos, const int w, this->OnExec.connect(sl); } +void CComponentsForm::Init( const int& x_pos, const int& y_pos, const int& w, const int& h, + const fb_pixel_t& color_frame, + const fb_pixel_t& color_body, + const fb_pixel_t& color_shadow) +{ + setDimensionsAll(x_pos, y_pos, w, h); + setColorAll(color_frame, color_body, color_shadow); +} + CComponentsForm::~CComponentsForm() { clear(); @@ -292,7 +294,7 @@ void CComponentsForm::insertCCItem(const uint& cc_item_id, CComponentsItem* cc_I if (v_cc_items.empty()){ addCCItem(cc_Item); - dprintf(DEBUG_DEBUG, "[CComponentsForm] %s insert cc_Item not possible, v_cc_items is empty, cc_Item added\n", __func__); + dprintf(DEBUG_NORMAL, "[CComponentsForm] %s insert cc_Item not possible, v_cc_items is empty, cc_Item added\n", __func__); }else{ v_cc_items.insert(v_cc_items.begin()+cc_item_id, cc_Item); cc_Item->setParent(this); @@ -520,23 +522,23 @@ void CComponentsForm::paintCCItems() cc_item->allowPaint(item_visible); } } - -void CComponentsForm::hide(bool no_restore) +#if 0 +void CComponentsForm::hide() { // hack: ensure hiding of minitv during hide of forms and inherited classes, // because the handling of minitv items are different to other item types // and need an explizit call of hide() for(size_t i=0; igetItemType() == CC_ITEMTYPE_PIP){ - v_cc_items[i]->hide(); + v_cc_items[i]->kill(); break; } } //hide body - hideCCItem(no_restore); + CComponents::hide(); } - +#endif //erase or paint over rendered objects void CComponentsForm::killCCItems(const fb_pixel_t& bg_color, bool ignore_parent) { @@ -649,3 +651,47 @@ void CComponentsForm::ScrollPage(int direction, bool do_paint) OnAfterScrollPage(); } + +bool CComponentsForm::clearSavedScreen() +{ + if (CCDraw::clearSavedScreen()){ + for(size_t i=0; iclearSavedScreen(); + return true; + } + + return false; +} + +bool CComponentsForm::clearPaintCache() +{ + if (CCDraw::clearPaintCache()){ + for(size_t i=0; iclearPaintCache(); + return true; + } + + return false; +} + +//clean old gradient buffer +bool CComponentsForm::clearFbGradientData() +{ + if (CCDraw::clearFbGradientData()){ + for(size_t i=0; iclearFbGradientData(); + return true; + } + + return false; +} + +bool CComponentsForm::enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color, const int& direction) +{ + if (CCDraw::enableColBodyGradient(enable_mode, sec_color, direction)){ + for (size_t i= 0; i< v_cc_items.size(); i++) + v_cc_items[i]->clearScreenBuffer(); + return true; + } + return false; +} diff --git a/src/gui/components/cc_frm.h b/src/gui/components/cc_frm.h index 4736598c8..52c3d5934 100644 --- a/src/gui/components/cc_frm.h +++ b/src/gui/components/cc_frm.h @@ -26,7 +26,8 @@ #include "config.h" -#include +#include "cc_base.h" +#include "cc_item.h" #include "cc_frm_scrollbar.h" class CComponentsForm : public CComponentsItem @@ -55,10 +56,16 @@ class CComponentsForm : public CComponentsItem ///enable/disable page scrolling, default enabled with page scroll mode up/down keys, see also enablePageScroll() int page_scroll_mode; + ///initialize basic properties + virtual void Init( const int& x_pos, const int& y_pos, const int& w, const int& h, + const fb_pixel_t& color_frame, + const fb_pixel_t& color_body, + const fb_pixel_t& color_shadow); + public: CComponentsForm( const int x_pos = 0, const int y_pos = 0, const int w = 800, const int h = 600, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -66,8 +73,6 @@ class CComponentsForm : public CComponentsItem ///paints current form on screen, for paint a page use paintPage() void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); - ///hides current form, background will be restored, if parameter = false - void hide(bool no_restore = false); ///same like CComponentsItem::kill(), but erases all embedded items inside of parent at once, this = parent ///NOTE: Items always have parent bindings to "this" and use the parent background color as default! Set parameter 'ignore_parent=true' to ignore parent background color! @@ -190,6 +195,14 @@ class CComponentsForm : public CComponentsItem }; ///scroll page and paint current selected page, if parameter2 = true (default) virtual void ScrollPage(int direction = SCROLL_P_DOWN, bool do_paint = true); + + virtual bool enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_colorconst, const int& direction = -1 /*CFrameBuffer::gradientVertical*/); + ///cleans saved screen buffer include from sub items, required by hide(), returns true if any buffer was deleted + virtual bool clearSavedScreen(); + ///cleanup paint cache include from sub items, removes saved buffer contents from cached foreground layers, returns true if any buffer was removed + virtual bool clearPaintCache(); + ///cleanup old gradient buffers include from sub items, returns true if any gradient buffer data was removed + virtual bool clearFbGradientData(); }; #endif diff --git a/src/gui/components/cc_frm_button.cpp b/src/gui/components/cc_frm_button.cpp index f81450ecb..ab4b45563 100644 --- a/src/gui/components/cc_frm_button.cpp +++ b/src/gui/components/cc_frm_button.cpp @@ -40,11 +40,11 @@ CComponentsButton::CComponentsButton( const int& x_pos, const int& y_pos, const CComponentsForm* parent, bool selected, bool enabled, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { cc_btn_capt_locale = NONEXISTANT_LOCALE; - initVarButton(x_pos, y_pos, w, h, caption, icon_name, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow); + initVarButton(x_pos, y_pos, w, h, caption, icon_name, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow); } CComponentsButton::CComponentsButton( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -52,11 +52,11 @@ CComponentsButton::CComponentsButton( const int& x_pos, const int& y_pos, const CComponentsForm* parent, bool selected, bool enabled, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { cc_btn_capt_locale = caption_locale; - initVarButton(x_pos, y_pos, w, h, g_Locale->getText(cc_btn_capt_locale), icon_name, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow); + initVarButton(x_pos, y_pos, w, h, g_Locale->getText(cc_btn_capt_locale), icon_name, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow); } CComponentsButton::CComponentsButton( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -64,11 +64,11 @@ CComponentsButton::CComponentsButton( const int& x_pos, const int& y_pos, const CComponentsForm* parent, bool selected, bool enabled, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { string _icon_name = icon_name == NULL ? "" : string(icon_name); - initVarButton(x_pos, y_pos, w, h, caption, _icon_name, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow); + initVarButton(x_pos, y_pos, w, h, caption, _icon_name, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow); } CComponentsButton::CComponentsButton( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -76,12 +76,12 @@ CComponentsButton::CComponentsButton( const int& x_pos, const int& y_pos, const CComponentsForm* parent, bool selected, bool enabled, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { string _icon_name = icon_name == NULL ? "" : string(icon_name); cc_btn_capt_locale = caption_locale; - initVarButton(x_pos, y_pos, w, h, g_Locale->getText(cc_btn_capt_locale), _icon_name, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow); + initVarButton(x_pos, y_pos, w, h, g_Locale->getText(cc_btn_capt_locale), _icon_name, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow); } void CComponentsButton::initVarButton( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -90,7 +90,7 @@ void CComponentsButton::initVarButton( const int& x_pos, const int& y_pos, const CComponentsForm* parent, bool selected, bool enabled, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON; @@ -99,13 +99,13 @@ void CComponentsButton::initVarButton( const int& x_pos, const int& y_pos, const y = y_pos; width = w; height = h; - shadow = has_shadow; + shadow = shadow_mode; shadow_w = SHADOW_OFFSET; - col_body_gradient = false/*g_settings.gradiant*/; //gradient is prepared for use but disabled at the moment till some other parts of gui parts are provide gradient + cc_body_gradient_enable = false/*g_settings.gradiant*/; //gradient is prepared for use but disabled at the moment till some other parts of gui parts are provide gradient setColBodyGradient(CColorGradient::gradientLight2Dark, CFrameBuffer::gradientVertical, CColorGradient::light); col_frame = color_frame; - col_body = col_body_gradient? COL_DARK_GRAY : color_body; + col_body = cc_body_gradient_enable? COL_DARK_GRAY : color_body; col_shadow = color_shadow; cc_item_enabled = enabled; @@ -115,8 +115,8 @@ void CComponentsButton::initVarButton( const int& x_pos, const int& y_pos, const append_y_offset = 0; corner_rad = 0; - cc_btn_capt_col = col_body_gradient ? COL_BUTTON_TEXT_ENABLED : COL_INFOBAR_SHADOW_TEXT; - cc_btn_capt_disable_col = col_body_gradient ? COL_BUTTON_TEXT_DISABLED : COL_MENUCONTENTINACTIVE_TEXT; + cc_btn_capt_col = cc_body_gradient_enable ? COL_BUTTON_TEXT_ENABLED : COL_INFOBAR_SHADOW_TEXT; + cc_btn_capt_disable_col = cc_body_gradient_enable ? COL_BUTTON_TEXT_DISABLED : COL_MENUCONTENTINACTIVE_TEXT; cc_btn_icon_obj = NULL; cc_btn_capt_obj = NULL; cc_btn_dy_font = CNeutrinoFonts::getInstance(); @@ -174,7 +174,7 @@ void CComponentsButton::initCaption() if (cc_btn_capt_obj == NULL){ cc_btn_capt_obj = new CComponentsLabel(); cc_btn_capt_obj->doPaintBg(false); - cc_btn_capt_obj->enableTboxSaveScreen(save_tbox_screen); + cc_btn_capt_obj->enableTboxSaveScreen(cc_txt_save_screen); addCCItem(cc_btn_capt_obj); } }else{ diff --git a/src/gui/components/cc_frm_button.h b/src/gui/components/cc_frm_button.h index a60529ccd..44a688b32 100644 --- a/src/gui/components/cc_frm_button.h +++ b/src/gui/components/cc_frm_button.h @@ -31,6 +31,7 @@ #include "cc_frm_chain.h" #include "cc_item_picture.h" #include "cc_item_text.h" +#include #include #include #include @@ -43,7 +44,7 @@ /*! Shows a button box with caption and optional icon. */ -class CComponentsButton : public CComponentsFrmChain +class CComponentsButton : public CComponentsFrmChain, public CCTextScreen { protected: ///object: picture object @@ -58,7 +59,7 @@ class CComponentsButton : public CComponentsFrmChain CComponentsForm* parent, bool selected, bool enabled, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow); ///property: button text as string, see also setCaption() and getCaptionString() @@ -101,7 +102,7 @@ class CComponentsButton : public CComponentsFrmChain CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_DARK_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); CComponentsButton( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -110,7 +111,7 @@ class CComponentsButton : public CComponentsFrmChain CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_DARK_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); CComponentsButton( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -119,7 +120,7 @@ class CComponentsButton : public CComponentsFrmChain CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_DARK_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); CComponentsButton( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -128,7 +129,7 @@ class CComponentsButton : public CComponentsFrmChain CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_DARK_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); ///set text color @@ -181,9 +182,9 @@ class CComponentsButtonRed : public CComponentsButton CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsButton(x_pos, y_pos, w, h, caption, NEUTRINO_ICON_BUTTON_RED, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow) + :CComponentsButton(x_pos, y_pos, w, h, caption, NEUTRINO_ICON_BUTTON_RED, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON_RED; }; @@ -192,9 +193,9 @@ class CComponentsButtonRed : public CComponentsButton CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsButton(x_pos, y_pos, w, h, caption_locale, NEUTRINO_ICON_BUTTON_RED, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow) + :CComponentsButton(x_pos, y_pos, w, h, caption_locale, NEUTRINO_ICON_BUTTON_RED, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON_RED; }; @@ -212,9 +213,9 @@ class CComponentsButtonGreen : public CComponentsButton CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsButton(x_pos, y_pos, w, h, caption, NEUTRINO_ICON_BUTTON_GREEN, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow) + :CComponentsButton(x_pos, y_pos, w, h, caption, NEUTRINO_ICON_BUTTON_GREEN, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON_GREEN; }; @@ -223,9 +224,9 @@ class CComponentsButtonGreen : public CComponentsButton CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsButton(x_pos, y_pos, w, h, caption_locale, NEUTRINO_ICON_BUTTON_GREEN, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow) + :CComponentsButton(x_pos, y_pos, w, h, caption_locale, NEUTRINO_ICON_BUTTON_GREEN, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON_GREEN; }; @@ -243,9 +244,9 @@ class CComponentsButtonYellow : public CComponentsButton CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsButton(x_pos, y_pos, w, h, caption, NEUTRINO_ICON_BUTTON_YELLOW, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow) + :CComponentsButton(x_pos, y_pos, w, h, caption, NEUTRINO_ICON_BUTTON_YELLOW, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON_YELLOW; }; @@ -254,9 +255,9 @@ class CComponentsButtonYellow : public CComponentsButton CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsButton(x_pos, y_pos, w, h, caption_locale, NEUTRINO_ICON_BUTTON_YELLOW, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow) + :CComponentsButton(x_pos, y_pos, w, h, caption_locale, NEUTRINO_ICON_BUTTON_YELLOW, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON_YELLOW; }; @@ -274,9 +275,9 @@ class CComponentsButtonBlue : public CComponentsButton CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsButton(x_pos, y_pos, w, h, caption, NEUTRINO_ICON_BUTTON_BLUE, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow) + :CComponentsButton(x_pos, y_pos, w, h, caption, NEUTRINO_ICON_BUTTON_BLUE, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON_BLUE; }; @@ -285,9 +286,9 @@ class CComponentsButtonBlue : public CComponentsButton CComponentsForm *parent = NULL, bool selected = false, bool enabled = true, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_BUTTON_BODY, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsButton(x_pos, y_pos, w, h, caption_locale, NEUTRINO_ICON_BUTTON_BLUE, parent, selected, enabled, has_shadow, color_frame, color_body, color_shadow) + :CComponentsButton(x_pos, y_pos, w, h, caption_locale, NEUTRINO_ICON_BUTTON_BLUE, parent, selected, enabled, shadow_mode, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_BUTTON_BLUE; }; diff --git a/src/gui/components/cc_frm_chain.cpp b/src/gui/components/cc_frm_chain.cpp index b3f8b9824..c6e666fe1 100644 --- a/src/gui/components/cc_frm_chain.cpp +++ b/src/gui/components/cc_frm_chain.cpp @@ -33,12 +33,12 @@ CComponentsFrmChain::CComponentsFrmChain( const int& x_pos, const int& y_pos, co const std::vector *v_items, int direction, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t& color_frame, fb_pixel_t& color_body, fb_pixel_t& color_shadow) { - initVarChain(x_pos, y_pos, w, h, v_items, direction, parent, has_shadow, color_frame, color_body, color_shadow); + initVarChain(x_pos, y_pos, w, h, v_items, direction, parent, shadow_mode, color_frame, color_body, color_shadow); } @@ -46,7 +46,7 @@ void CComponentsFrmChain::initVarChain( const int& x_pos, const int& y_pos, cons const std::vector *v_items, int direction, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t& color_frame, fb_pixel_t& color_body, fb_pixel_t& color_shadow) @@ -59,7 +59,7 @@ void CComponentsFrmChain::initVarChain( const int& x_pos, const int& y_pos, cons width = w; height = h; - shadow = has_shadow; + shadow = shadow_mode; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; diff --git a/src/gui/components/cc_frm_chain.h b/src/gui/components/cc_frm_chain.h index 2ce8b7e42..2a13a14be 100644 --- a/src/gui/components/cc_frm_chain.h +++ b/src/gui/components/cc_frm_chain.h @@ -51,7 +51,7 @@ class CComponentsFrmChain : public CComponentsForm const std::vector *v_items, int direction, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t& color_frame, fb_pixel_t& color_body, fb_pixel_t& color_shadow); @@ -66,7 +66,7 @@ class CComponentsFrmChain : public CComponentsForm const std::vector *v_items = NULL, int direction = CC_DIR_X, CComponentsForm* parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t& color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t& color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t& color_shadow = COL_MENUCONTENTDARK_PLUS_0); diff --git a/src/gui/components/cc_frm_clock.cpp b/src/gui/components/cc_frm_clock.cpp index 1db2ac0da..313b05cc2 100644 --- a/src/gui/components/cc_frm_clock.cpp +++ b/src/gui/components/cc_frm_clock.cpp @@ -3,7 +3,7 @@ Copyright (C) 2001 by Steffen Hehn 'McClean' Generic GUI-related component. - Copyright (C) 2013, 2014 Thilo Graf 'dbt' + Copyright (C) 2013-2015 Thilo Graf 'dbt' License: GPL @@ -27,69 +27,91 @@ #include #include -#include #include "cc_frm_clock.h" #include -#include + #include #include #include #include +#include using namespace std; - -CComponentsFrmClock::CComponentsFrmClock( const int& x_pos, const int& y_pos, const int& w, const int& h, - const char* format_str, +CComponentsFrmClock::CComponentsFrmClock( const int& x_pos, + const int& y_pos, + Font * font, + const char* prformat_str, + const char* secformat_str, bool activ, + const int& interval_seconds, CComponentsForm* parent, - bool has_shadow, - fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) + int shadow_mode, + fb_pixel_t color_frame, + fb_pixel_t color_body, + fb_pixel_t color_shadow, + int font_style + ) { + cc_item_type = CC_ITEMTYPE_FRM_CLOCK; + x = x_pos; y = y_pos; - width = w; - height = h; - shadow = has_shadow; + + shadow = shadow_mode; shadow_w = SHADOW_OFFSET; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; - cc_item_type = CC_ITEMTYPE_FRM_CLOCK; - corner_rad = RADIUS_SMALL; + corner_rad = RADIUS_SMALL; - cl_font_type = SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO; - cl_font = &g_Font[cl_font_type]; - dyn_font_size = 0; + //init default format and text color + setClockFormat(prformat_str, secformat_str); + cl_col_text = COL_MENUCONTENT_TEXT; - cl_col_text = COL_MENUCONTENT_TEXT; - cl_format_str = format_str; - cl_align = CC_ALIGN_VER_CENTER | CC_ALIGN_HOR_CENTER; + //init default font + cl_font = font; + cl_font_style = font_style; + if (cl_font == NULL){ + int dx = 0; + int dy = 30; + setClockFont(*CNeutrinoFonts::getInstance()->getDynFont(dx, dy, cl_format_str, cl_font_style)); + } - cl_thread = 0; - cl_interval = 1; + //init general clock dimensions + height = cl_font->getHeight(); + width = cl_font->getRenderWidth(cl_format_str); - activeClock = true; - cl_blink_str = format_str; - paintClock = false; - - activeClock = activ; + //set default text background behavior + cc_txt_save_screen = false; + //set default running clock properties + cl_interval = interval_seconds; + cl_timer = NULL; + paintClock = false; +#if 0 may_blit = true; +#endif + //general init initCCLockItems(); initParent(parent); - if (activeClock) - startThread(); + //init slot for running clock + cl_sl = sigc::mem_fun0(*this, &CComponentsFrmClock::ShowTime); + + //run clock already if required + if (activ) + startClock(); } CComponentsFrmClock::~CComponentsFrmClock() { - stopThread(); + if (cl_timer) + delete cl_timer; } @@ -97,8 +119,34 @@ void CComponentsFrmClock::initTimeString() { struct tm t; time_t ltime; - ltime=time(NULL); - strftime(cl_timestr, sizeof(cl_timestr), getTimeFormat(ltime), localtime_r(<ime, &t)); + ltime=time(<ime); + + toggleFormat(); + + strftime(cl_timestr, sizeof(cl_timestr), cl_format.c_str(), localtime_r(<ime, &t)); +} + +//formating time string with possible blink string +void CComponentsFrmClock::toggleFormat() +{ + if (cl_format_str.length() != cl_blink_str.length()) + kill(); + + if (cl_format == cl_blink_str) + cl_format = cl_format_str; + else + cl_format = cl_blink_str; +} + +//set current time format string +void CComponentsFrmClock::setClockFormat(const char* prformat_str, const char* secformat_str) +{ + cl_format_str = prformat_str; + + if (secformat_str == NULL) + cl_blink_str = cl_format_str; + else + cl_blink_str = secformat_str; } // How does it works? @@ -117,23 +165,20 @@ void CComponentsFrmClock::initTimeString() void CComponentsFrmClock::initCCLockItems() { + //prepare and set current time string initTimeString(); string s_time = cl_timestr; - - //get minimal required height, width from raw text - int min_text_w = (*getClockFont())->getRenderWidth(s_time); - int min_text_h = (*getClockFont())->getHeight(); - height = max(height, min_text_h); - width = max(width, min_text_w); - int cl_x = 0; - int cl_h = min_text_h; - int cl_y = 0; - int w_lbl_tmp = 0; - - //create label objects and add to container, ensure count of items = count of chars (one char = one segment) - if (v_cc_items.size() != s_time.size()){ - + /* create label objects and add to container, ensure that count of items = count of chars (one char = one segment) + * this is required for the case, if any time string format was changed + */ + if (v_cc_items.empty() || (v_cc_items.size() != s_time.size())){ + //exit on empty time string + if (s_time.empty()){ + clear(); + return; + } + //clean up possible old items before add new items clear(); @@ -141,10 +186,10 @@ void CComponentsFrmClock::initCCLockItems() for (size_t i = 0; i < s_time.size(); i++){ CComponentsLabel * lbl = new CComponentsLabel(); addCCItem(lbl); - + //background paint of item is not required lbl->doPaintBg(false); - + //set corner properties of label item lbl->setCorner(corner_rad-fr_thickness, corner_type); @@ -152,14 +197,31 @@ void CComponentsFrmClock::initCCLockItems() lbl->setTextBorderWidth(0,0); } } - - //calculate minimal separator width, we use char size of some possible chars + + /*calculate minimal separator width, we use char size of some possible chars + * TODO: it's not really generic at the moment + */ int minSepWidth = 0; string sep[] ={" ", ".", ":"}; for (size_t i = 0; i < sizeof(sep)/sizeof(sep[0]); i++) - minSepWidth = max((*getClockFont())->getRenderWidth(sep[i]), minSepWidth); + minSepWidth = max(cl_font->getRenderWidth(sep[i]), minSepWidth); - //modify available label items with current segment chars + //get minimal required dimensions for segements from current format string + int w_text_min = max(cl_font->getRenderWidth(s_time), width); + int h_text_min = max(cl_font->getHeight(), height); + + //init some temporary variables + int x_tmp = x; + int h_tmp = h_text_min; + int y_tmp = y; + + //summary of all segments (labels) + int w_segments = 0; + + /* modify available label items with current segment chars + * we are using segments with only one char per segment, + * these chars are predefined via format string + */ for (size_t i = 0; i < v_cc_items.size(); i++) { //v_cc_items are only available as CComponent-items here, so we must cast them before @@ -178,21 +240,26 @@ void CComponentsFrmClock::initCCLockItems() //extract timestring segment (char) string stmp = s_time.substr(i, 1); + int w_tmp = minSepWidth; //get width of current segment - int wtmp = 0; if (isdigit(stmp.at(0)) ) //check for digits, if true, we use digit width - wtmp = (*getClockFont())->getMaxDigitWidth(); + w_tmp = cl_font->getMaxDigitWidth(); else //not digit found, we use render width or minimal width - wtmp = max((*getClockFont())->getRenderWidth(stmp), minSepWidth); + w_tmp = max(cl_font->getRenderWidth(stmp), minSepWidth); + //lbl->enablePaintCache(); //set size, text, color of current item - lbl->setDimensionsAll(cl_x, cl_y, wtmp, cl_h); - lbl->setTextColor(cl_col_text); + lbl->setDimensionsAll(x_tmp, y_tmp, w_tmp, h_tmp); lbl->setColorAll(col_frame, col_body, col_shadow); - lbl->setText(stmp, CTextBox::CENTER, *getClockFont()); + lbl->forceTextPaint(false); + lbl->setText(stmp, CTextBox::CENTER, cl_font, cl_col_text, cl_font_style); + //init background behavior of segment + //printf("[CComponentsFrmClock] [%s - %d] paint_bg: [%d] gradient_mode = [%d], text save screen mode = [%d]\n", __func__, __LINE__, paint_bg, cc_body_gradient_enable, cc_txt_save_screen); + lbl->doPaintBg(false); lbl->doPaintTextBoxBg(paint_bg); - lbl->enableTboxSaveScreen(save_tbox_screen); + bool save_txt_screen = cc_txt_save_screen || (!paint_bg || cc_body_gradient_enable); + lbl->enableTboxSaveScreen(save_txt_screen); //use matching height for digits for better vertical centerring into form CTextBox* ctb = lbl->getCTextBoxObject(); @@ -203,140 +270,99 @@ void CComponentsFrmClock::initCCLockItems() bool force_txt_and_bg = (lbl->textChanged() || this->paint_bg); lbl->forceTextPaint(force_txt_and_bg); #endif - //set xpos of item - cl_x += wtmp; + //set xpos and width of item (segment) + lbl->setWidth(w_tmp); + x_tmp += w_tmp; - lbl->setWidth(wtmp); - - //set current width for form - w_lbl_tmp += wtmp; + //sum required width for clock (this) + w_segments += w_tmp; + h_text_min = max(lbl->getHeight(), height); + height = max(lbl->getHeight(), height); } - //set required width - width = max(width, w_lbl_tmp); - - initSegmentAlign(&w_lbl_tmp, &min_text_h); -} - -//handle alignment -void CComponentsFrmClock::initSegmentAlign(int* segment_width, int* segment_height) -{ - int wadd = 0; - int hadd = 0; - int* w_lbl_tmp = segment_width; - int* min_text_h = segment_height; + //set required width for clock (this) + width = max(w_text_min, w_segments); //use first item as reference and set x and y position to the 1st segement item with definied alignment - if (cl_align & CC_ALIGN_RIGHT){ - wadd = width-*w_lbl_tmp; - v_cc_items[0]->setXPos(wadd); - } - else if (cl_align & CC_ALIGN_LEFT){ - v_cc_items[0]->setXPos(wadd); - } - else if (cl_align & CC_ALIGN_HOR_CENTER){ - hadd = height/2-*min_text_h/2; - v_cc_items[0]->setYPos(hadd); - } + int x_lbl = width/2-w_segments/2; + v_cc_items[0]->setXPos(x_lbl); - if (cl_align & CC_ALIGN_TOP){ - v_cc_items[0]->setYPos(hadd); - } - else if (cl_align & CC_ALIGN_BOTTOM){ - hadd = height-*min_text_h; - v_cc_items[0]->setYPos(hadd); - } - else if (cl_align & CC_ALIGN_VER_CENTER){ - wadd = width/2-*w_lbl_tmp/2; - v_cc_items[0]->setXPos(wadd); - } + int y_lbl = height/2-h_text_min/2; + v_cc_items[0]->setYPos(y_lbl); //set all evaluated position values to all other segement items for (size_t i = 1; i < v_cc_items.size(); i++){ - wadd += v_cc_items[i-1]->getWidth(); - v_cc_items[i]->setPos(wadd, hadd); + x_lbl += v_cc_items[i-1]->getWidth(); + v_cc_items[i]->setPos(x_lbl, y_lbl); } } -//thread handle -void* CComponentsFrmClock::initClockThread(void *arg) -{ - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0); - pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS,0); - CComponentsFrmClock *clock = static_cast(arg); - //start loop for paint - while (true) { - clock->mutex.lock(); - if (clock->paintClock) - clock->paint(CC_SAVE_SCREEN_NO); - clock->mutex.unlock(); - int interval = clock->cl_interval; - mySleep(interval); +//this member is provided for slot with timer event "OnTimer" +void CComponentsFrmClock::ShowTime() +{ + if (paintClock) { + //paint segements, but wihtout saved backgrounds + paint(CC_SAVE_SCREEN_NO); } - return 0; } -//start up ticking clock with own thread, return true on succses -bool CComponentsFrmClock::startThread() +//start up ticking clock controled by timer with signal/slot, return true on succses +bool CComponentsFrmClock::startClock() { - void *ptr = static_cast(this); + if (cl_interval <= 0){ + dprintf(DEBUG_NORMAL, "[CComponentsFrmClock] [%s] clock is set to active, but interval is initialized with value %d ...\n", __func__, cl_interval); + return false; + } + + if (cl_timer == NULL){ + cl_timer = new CComponentsTimer(); + dprintf(DEBUG_INFO, "[CComponentsFrmClock] [%s] init slot...\n", __func__); + cl_timer->OnTimer.connect(cl_sl); + } + cl_timer->setTimerIntervall(cl_interval); + + if (cl_timer->isRun()) + return true; - if(!cl_thread) { - int res = pthread_create (&cl_thread, NULL, initClockThread, ptr) ; - if (res != 0){ - printf("[CComponentsFrmClock] [%s] pthread_create %s\n", __func__, strerror(errno)); - return false; - } - pthread_detach(cl_thread); - } - return true; + return false; } -//stop ticking clock and kill thread, return true on succses -bool CComponentsFrmClock::stopThread() +//stop ticking clock and internal timer, return true on succses +bool CComponentsFrmClock::stopClock() { - if(cl_thread) { - int res = pthread_cancel(cl_thread); - if (res != 0){ - printf("[CComponentsFrmClock] [%s] pthread_cancel %s\n", __func__, strerror(errno)); - return false; + if (cl_timer){ + if (cl_timer->stopTimer()){ + dprintf(DEBUG_INFO, "[CComponentsFrmClock] [%s] stopping clock...\n", __func__); + delete cl_timer; + cl_timer = NULL; + return true; } -#if 0 - res = pthread_join(cl_thread, NULL); - if (res != 0){ - printf("[CComponentsFrmClock] [%s] pthread_join %s\n", __func__, strerror(errno)); - return false; - } -#endif + else + dprintf(DEBUG_NORMAL, "[CComponentsFrmClock] [%s] stopping timer failed...\n", __func__); } - hide(); - cl_thread = 0; - return true; + return false; } bool CComponentsFrmClock::Start(bool do_save_bg) { - if (!activeClock) - return false; - if (!cl_thread) - startThread(); - if (cl_thread) { + if (startClock()) { //ensure paint of segements on first paint paint(do_save_bg); paintClock = true; + return true; } - return cl_thread == 0 ? false : true; + return false; } bool CComponentsFrmClock::Stop() { - if (!activeClock) - return false; - mutex.lock(); - paintClock = false; - mutex.unlock(); - return cl_thread == 0 ? false : true; + if (stopClock()){ + paintClock = false; + return true; + } + + return false; } void CComponentsFrmClock::paint(bool do_save_bg) @@ -345,38 +371,85 @@ void CComponentsFrmClock::paint(bool do_save_bg) initCCLockItems(); //paint form contents - paintForm(do_save_bg); - + CComponentsForm::paint(do_save_bg); +#if 0 //has no effect if (may_blit) frameBuffer->blit(); +#endif } -void CComponentsFrmClock::setClockFontSize(int font_size) +void CComponentsFrmClock::setClockFont(Font *font, const int& style) { - int tmp_w = 0; - dyn_font_size = font_size; - cl_font = CNeutrinoFonts::getInstance()->getDynFont(tmp_w, dyn_font_size, "", CNeutrinoFonts::FONT_STYLE_BOLD, CNeutrinoFonts::FONT_ID_INFOCLOCK); + if (cl_font != font) + cl_font = font; + + if (style != -1) + cl_font_style = style; + +// setHeight(cl_font->getHeight()); +// setWidth(cl_font->getRenderWidth(cl_format_str)); + initCCLockItems(); } -void CComponentsFrmClock::setClockFont(int font) +Font* CComponentsFrmClock::getClockFont() { - cl_font_type = font; - cl_font = &g_Font[cl_font_type]; -} - -Font** CComponentsFrmClock::getClockFont() -{ - if (dyn_font_size == 0) - cl_font = &g_Font[cl_font_type]; return cl_font; - } -void CComponentsFrmClock::setClockActiv(bool activ/* = true*/) +void CComponentsFrmClock::kill(const fb_pixel_t& bg_color, bool ignore_parent) { - activeClock = activ; - if (activ && !cl_thread) - startThread(); - if (!activ && cl_thread) - stopThread(); + Stop(); + CComponentsForm::kill(bg_color, ignore_parent); +} + +void CComponentsFrmClock::enableSegmentSaveScreen(bool mode) +{ + if (cc_txt_save_screen == mode || v_cc_items.empty()) + return; + + cc_txt_save_screen = mode; + + for (size_t i = 0; i < v_cc_items.size(); i++){ + CComponentsLabel *seg = static_cast (v_cc_items[i]); + //seg->clearSavedScreen(); + seg->enableTboxSaveScreen(cc_txt_save_screen); + } +} + +void CComponentsFrmClock::setHeight(const int& h) +{ + if (h == height) + return; + + int f_height = cl_font->getHeight(); + if (h != f_height){ + dprintf(DEBUG_NORMAL, "\033[33m[CComponentsFrmClock]\t[%s - %d], font height is different than current height [%d], using [%d] ...\033[0m\n", __func__, __LINE__, h, f_height); + CCDraw::setHeight(f_height); + }else + CCDraw::setHeight(h); + initCCLockItems(); +} + +void CComponentsFrmClock::setWidth(const int& w) +{ + if (w == width) + return; + + int f_width = cl_font->getRenderWidth(cl_format_str); + if (w != f_width){ + dprintf(DEBUG_NORMAL, "\033[33m[CComponentsFrmClock]\t[%s - %d], font width is different than current width [%d], using [%d] ...\033[0m\n", __func__, __LINE__, w, f_width); + CCDraw::setWidth(f_width); + }else + CCDraw::setWidth(w); + initCCLockItems(); +} + +bool CComponentsFrmClock::enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color) +{ + if (CCDraw::enableColBodyGradient(enable_mode, sec_color)){ + for (size_t i = 0; i < v_cc_items.size(); i++) + static_cast (v_cc_items[i])->getCTextBoxObject()->clearScreenBuffer(); + return true; + } + return false; } diff --git a/src/gui/components/cc_frm_clock.h b/src/gui/components/cc_frm_clock.h index 64e6a6365..6b91c836f 100644 --- a/src/gui/components/cc_frm_clock.h +++ b/src/gui/components/cc_frm_clock.h @@ -3,7 +3,7 @@ Copyright (C) 2001 by Steffen Hehn 'McClean' Classes for generic GUI-related components. - Copyright (C) 2012, 2013, Thilo Graf 'dbt' + Copyright (C) 2012-2015, Thilo Graf 'dbt' License: GPL @@ -31,120 +31,142 @@ #include #endif -#include -#include -#include - +#include #include "cc_base.h" #include "cc_frm.h" - - +#include "cc_timer.h" +#include "cc_text_screen.h" //! Sub class of CComponents. Show clock with digits on screen. /*! Usable as simple fixed display or as ticking clock. */ -class CComponentsFrmClock : public CComponentsForm +class CComponentsFrmClock : public CComponentsForm, public CCTextScreen { private: - -// bool cl_force_segment_paint; + CComponentsTimer *cl_timer; + void ShowTime(); +#if 0 bool may_blit; - +#endif + protected: - ///thread - pthread_t cl_thread; + ///slot for timer event, reserved for ShowTime() + sigc::slot0 cl_sl; + ///refresh interval in seconds int cl_interval; - ///init function to start clock in own thread - static void* initClockThread(void *arg); ///raw time chars char cl_timestr[20]; ///handle paint clock within thread and is not similar to cc_allow_paint bool paintClock; - //TODO: please add comments! - bool activeClock; ///object: font render object - Font **cl_font; - - int cl_font_type; - int dyn_font_size; + Font *cl_font; + int cl_font_style; ///text color int cl_col_text; - ///time format - const char *cl_format_str; - ///time format for blink - const char *cl_blink_str; - ///time string align, default align is ver and hor centered - int cl_align; + + ///current time format + std::string cl_format; + ///primary time format + std::string cl_format_str; + ///secondary time format for blink + std::string cl_blink_str; ///initialize clock contents void initCCLockItems(); ///initialize timestring, called in initCCLockItems() virtual void initTimeString(); - ///initialize of general alignment of timestring segments within form area - void initSegmentAlign(int* segment_width, int* segment_height); - //return current time string format - const char *getTimeFormat(time_t when) { return (when & 1) ? cl_format_str : cl_blink_str; } + + ///start ticking clock, returns true on success, if false causes log output + bool startClock(); + ///stop ticking clock, returns true on success, if false causes log output + bool stopClock(); + ///switch between primary and secondary format + void toggleFormat(); ///return pointer of font object - inline Font** getClockFont(); + Font* getClockFont(); public: - OpenThreads::Mutex mutex; - CComponentsFrmClock( const int& x_pos = 1, const int& y_pos = 1, const int& w = 200, const int& h = 48, + CComponentsFrmClock( const int& x_pos = 1, const int& y_pos = 1, + Font * font = NULL, const char* format_str = "%H:%M", + const char* secformat_str = NULL, bool activ=false, + const int& interval_seconds = 1, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, - fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); + int shadow_mode = CC_SHADOW_OFF, + fb_pixel_t color_frame = COL_LIGHT_GRAY, + fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, + fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, + int font_style = CNeutrinoFonts::FONT_STYLE_BOLD + ); virtual ~CComponentsFrmClock(); - ///set font type or font size for segments - virtual void setClockFont(int font); - virtual void setClockFontSize(int font_size); + /*! Sets font type for clock segments. + * 1st parameter expects a pointer to font type, usually a type from the global g_Font collection, but also possible + * are dynamic font. + * The use of NULL pointer enforces dynamic font. + * 2nd paramter is relevant for dynamic fonts only, you can use the enum types + * - FONT_STYLE_REGULAR + * - FONT_STYLE_BOLD + * - FONT_STYLE_ITALIC + * (see /.src/driver/neutrinofonts.h) + */ + void setClockFont(Font * font, const int& style = -1); ///set text color - virtual void setTextColor(fb_pixel_t color_text){ cl_col_text = color_text;}; + virtual void setTextColor(fb_pixel_t color_text){ cl_col_text = color_text;} - ///set alignment of timestring, possible modes see align types in cc_types.h - virtual void setClockAlignment(int align_type){cl_align = align_type;}; + ///set height of clock on screen + virtual void setHeight(const int& h); + ///set width of clock on screen + virtual void setWidth(const int& w); ///use string expession: "%H:%M" = 12:22, "%H:%M:%S" = 12:22:12 - virtual void setClockFormat(const char* format_str){cl_format_str = format_str;}; - - ///time format for blink ("%H %M", "%H:%M %S" etc.) - virtual void setClockBlink(const char* format_str){cl_blink_str = format_str;}; - - ///start ticking clock thread, returns true on success, if false causes log output - virtual bool startThread(); - ///stop ticking clock thread, returns true on success, if false causes log output - virtual bool stopThread(); + ///set current time format string, 1st parameter set the default format, 2nd parameter sets an alternatively format for use as blink effect + virtual void setClockFormat(const char* prformat_str, const char* secformat_str = NULL); + ///start and paint ticking clock virtual bool Start(bool do_save_bg = CC_SAVE_SCREEN_NO); + ///same like Start() but for usage as simple call without return value + virtual void unblock(/*bool do_save_bg = CC_SAVE_SCREEN_NO*/){Start(cc_save_bg);} + ///stop ticking clock, but don't hide, use kill() or hide() to remove from screen virtual bool Stop(); + ///same like Stop() but for usage as simple call without return value + virtual void block(){Stop();} + ///return true on blocked status, blocked means clock can be initalized but would be not paint, to unblock use unblock() + virtual bool isBlocked(void) {return !paintClock;} - ///returns true, if clock is running in thread - virtual bool isClockRun() const {return cl_thread == 0 ? false:true;}; + ///returns true, if clock is running + virtual bool isRun() const {return cl_timer ? true : false;}; ///set refresh interval in seconds, default value=1 (=1 sec) virtual void setClockIntervall(const int& seconds){cl_interval = seconds;}; ///show clock on screen virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); + ///hide clock on screen + virtual void hide(){Stop(); CComponentsForm::hide();} + ///does the same like kill() from base class, but stopping clock before kill + void kill(const fb_pixel_t& bg_color = COL_BACKGROUND_PLUS_0, bool ignore_parent = false); ///reinitialize clock contents virtual void refresh() { initCCLockItems(); } + ///allows to save bg screen behind text within segment objects, see also cl_save_segment_screen + void enableSegmentSaveScreen(bool mode); - ///set clock activ/inactiv - virtual void setClockActiv(bool activ = true); - + ///set color gradient on/off, returns true if gradient mode was changed + virtual bool enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color = 255 /*=COL_BACKGROUND*/); +#if 0 ///enable/disable automatic blitting void setBlit(bool _may_blit = true) { may_blit = _may_blit; } +#endif }; #endif diff --git a/src/gui/components/cc_frm_ext_text.cpp b/src/gui/components/cc_frm_ext_text.cpp index 49b0613e2..5d24e7d58 100644 --- a/src/gui/components/cc_frm_ext_text.cpp +++ b/src/gui/components/cc_frm_ext_text.cpp @@ -37,32 +37,32 @@ using namespace std; CComponentsExtTextForm::CComponentsExtTextForm( const int& x_pos, const int& y_pos, const int& w, const int& h, const std::string& label_text, const std::string& text, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t label_color, fb_pixel_t text_color, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { - initVarExtTextForm(x_pos, y_pos, w, h, label_text, text, parent, has_shadow, label_color, text_color, color_frame, color_body, color_shadow); + initVarExtTextForm(x_pos, y_pos, w, h, label_text, text, parent, shadow_mode, label_color, text_color, color_frame, color_body, color_shadow); initCCTextItems(); } CComponentsExtTextFormLocalized::CComponentsExtTextFormLocalized(const int& x_pos, const int& y_pos, const int& w, const int& h, const neutrino_locale_t& locale_label_text, const neutrino_locale_t& locale_text, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t label_color, fb_pixel_t text_color, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) : CComponentsExtTextForm( x_pos, y_pos, w, h, g_Locale->getText(locale_label_text), g_Locale->getText(locale_text), parent, - has_shadow, + shadow_mode, label_color, text_color, color_frame, color_body, color_shadow){}; void CComponentsExtTextForm::initVarExtTextForm(const int& x_pos, const int& y_pos, const int& w, const int& h, const std::string& label_text, const std::string& text, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t label_color, fb_pixel_t text_color, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) @@ -82,7 +82,7 @@ void CComponentsExtTextForm::initVarExtTextForm(const int& x_pos, const int& y_p ccx_label_text = label_text; ccx_text = text; - shadow = has_shadow; + shadow = shadow_mode; ccx_label_color = label_color; ccx_text_color = text_color; col_frame = color_frame; @@ -105,7 +105,7 @@ void CComponentsExtTextForm::initLabel() if (ccx_label_obj == NULL){ ccx_label_obj = new CComponentsLabel(); ccx_label_obj->doPaintBg(false); - ccx_label_obj->enableTboxSaveScreen(save_tbox_screen); + ccx_label_obj->enableTboxSaveScreen(cc_txt_save_screen); } //add label object @@ -128,7 +128,7 @@ void CComponentsExtTextForm::initText() if (ccx_text_obj == NULL){ ccx_text_obj = new CComponentsText(); ccx_text_obj->doPaintBg(false); - ccx_text_obj->enableTboxSaveScreen(save_tbox_screen); + ccx_text_obj->enableTboxSaveScreen(cc_txt_save_screen); } //add text object @@ -161,12 +161,12 @@ void CComponentsExtTextForm::setLabelAndText(const neutrino_locale_t& locale_lab setLabelAndText(g_Locale->getText(locale_label_text), g_Locale->getText(locale_text), font_text); } -void CComponentsExtTextForm::setLabelAndTexts(const string_ext_txt_t& texts) +void CComponentsExtTextForm::setLabelAndTexts(const cc_string_ext_txt_t& texts) { setLabelAndText(texts.label_text, texts.text, texts.font); } -void CComponentsExtTextForm::setLabelAndTexts(const locale_ext_txt_t& locale_texts) +void CComponentsExtTextForm::setLabelAndTexts(const cc_locale_ext_txt_t& locale_texts) { setLabelAndText(g_Locale->getText(locale_texts.label_text), g_Locale->getText(locale_texts.text), locale_texts.font); } diff --git a/src/gui/components/cc_frm_ext_text.h b/src/gui/components/cc_frm_ext_text.h index 66a2172fb..007680dea 100644 --- a/src/gui/components/cc_frm_ext_text.h +++ b/src/gui/components/cc_frm_ext_text.h @@ -28,7 +28,7 @@ #include "cc_item_text.h" -class CComponentsExtTextForm : public CComponentsForm +class CComponentsExtTextForm : public CComponentsForm, public CCTextScreen { private: ///property: content of label, see also setLabelAndText() @@ -69,7 +69,7 @@ class CComponentsExtTextForm : public CComponentsForm void initVarExtTextForm(const int& x_pos, const int& y_pos, const int& w, const int& h, const std::string& label_text, const std::string& text, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t label_color, fb_pixel_t text_color, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow); @@ -79,7 +79,7 @@ class CComponentsExtTextForm : public CComponentsForm CComponentsExtTextForm( const int& x_pos = 1, const int& y_pos = 1, const int& w = 300, const int& h = 48, const std::string& label_text = "", const std::string& text = "", CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t label_color = COL_MENUCONTENTINACTIVE_TEXT, fb_pixel_t text_color = COL_MENUCONTENT_TEXT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, @@ -94,10 +94,10 @@ class CComponentsExtTextForm : public CComponentsForm ///assigns text Font type void setLabelAndTextFont(Font* font); - ///assigns texts for label and text, parameter as struct (locale_ext_txt_t), parameters provide the same properties like setLabelAndText() - void setLabelAndTexts(const locale_ext_txt_t& texts); - ///assigns texts for label and text, parameter as struct (string_ext_txt_t), parameters provide the same properties like setLabelAndText() - void setLabelAndTexts(const string_ext_txt_t& locale_texts); + ///assigns texts for label and text, parameter as struct (cc_locale_ext_txt_t), parameters provide the same properties like setLabelAndText() + void setLabelAndTexts(const cc_locale_ext_txt_t& texts); + ///assigns texts for label and text, parameter as struct (cc_string_ext_txt_t), parameters provide the same properties like setLabelAndText() + void setLabelAndTexts(const cc_string_ext_txt_t& locale_texts); ///assigns colors for text for label text, parameter as fb_pixel_t void setLabelAndTextColor(const fb_pixel_t label_color , const fb_pixel_t text_color); @@ -124,7 +124,7 @@ class CComponentsExtTextFormLocalized : public CComponentsExtTextForm CComponentsExtTextFormLocalized(const int& x_pos = 1, const int& y_pos = 1, const int& w = 300, const int& h = 48, const neutrino_locale_t& locale_label_text = NONEXISTANT_LOCALE, const neutrino_locale_t& locale_text = NONEXISTANT_LOCALE, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t label_color = COL_MENUCONTENTINACTIVE_TEXT, fb_pixel_t text_color = COL_MENUCONTENT_TEXT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); diff --git a/src/gui/components/cc_frm_footer.cpp b/src/gui/components/cc_frm_footer.cpp index e95e42283..7edb21395 100644 --- a/src/gui/components/cc_frm_footer.cpp +++ b/src/gui/components/cc_frm_footer.cpp @@ -43,19 +43,19 @@ CComponentsFooter::CComponentsFooter(CComponentsForm* parent) CComponentsFooter::CComponentsFooter( const int& x_pos, const int& y_pos, const int& w, const int& h, const int& buttons, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow ) { //CComponentsFooter - initVarFooter(x_pos, y_pos, w, h, buttons, parent, has_shadow, color_frame, color_body, color_shadow); + initVarFooter(x_pos, y_pos, w, h, buttons, parent, shadow_mode, color_frame, color_body, color_shadow); } void CComponentsFooter::initVarFooter( const int& x_pos, const int& y_pos, const int& w, const int& h, const int& buttons, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow ) @@ -72,11 +72,11 @@ void CComponentsFooter::initVarFooter( const int& x_pos, const int& y_pos, const cch_font = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]; height = max(h, cch_font->getHeight()); - shadow = has_shadow; + shadow = shadow_mode; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; - col_body_gradient = false; /*g_settings.theme.Foot_gradient*/; //TODO: not implemented at the moment + cc_body_gradient_enable = cc_body_gradient_enable_old = g_settings.theme.menu_ButtonBar_gradient; //TODO: not complete implemented at the moment cc_body_gradient_direction = CFrameBuffer::gradientVertical; cc_body_gradient_mode = CColorGradient::gradientDark2Light; btn_auto_frame_col = false; @@ -145,6 +145,8 @@ void CComponentsFooter::setButtonLabels(const struct button_label_s * const cont CComponentsButton *btn = new CComponentsButton(0, CC_CENTERED, w_btn_min, height-height/(btn_contour ? 4 : 3), txt, btn_name); btn->setButtonFont(ccf_btn_font); btn->doPaintBg(btn_contour); + btn->enableFrame(btn_contour); + btn->setButtonTextColor(COL_INFOBAR_SHADOW_TEXT); btn->setButtonEventMsg(content[i].btn_msg); btn->setButtonResult(content[i].btn_result); btn->setButtonAlias(content[i].btn_alias); diff --git a/src/gui/components/cc_frm_footer.h b/src/gui/components/cc_frm_footer.h index 04871319a..9b30a7be8 100644 --- a/src/gui/components/cc_frm_footer.h +++ b/src/gui/components/cc_frm_footer.h @@ -62,7 +62,7 @@ class CComponentsFooter : public CComponentsHeader void initVarFooter( const int& x_pos, const int& y_pos, const int& w, const int& h = 0, const int& buttons = 0, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_INFOBAR_SHADOW_PLUS_1, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -83,7 +83,7 @@ class CComponentsFooter : public CComponentsHeader CComponentsFooter( const int& x_pos, const int& y_pos, const int& w, const int& h = 0, const int& buttons = 0, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_INFOBAR_SHADOW_PLUS_1, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); diff --git a/src/gui/components/cc_frm_header.cpp b/src/gui/components/cc_frm_header.cpp index 59359b7c8..f26bc4132 100644 --- a/src/gui/components/cc_frm_header.cpp +++ b/src/gui/components/cc_frm_header.cpp @@ -33,6 +33,12 @@ using namespace std; //------------------------------------------------------------------------------------------------------- + +// x/y width +// +---------------------------------------------------------+ +// ||icon |caption |clock|context buttons||height +// +---------------------------------------------------------+ + //sub class CComponentsHeader inherit from CComponentsForm CComponentsHeader::CComponentsHeader(CComponentsForm* parent) { @@ -45,12 +51,12 @@ CComponentsHeader::CComponentsHeader( const int& x_pos, const int& y_pos, const const std::string& icon_name, const int& buttons, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { - initVarHeader(x_pos, y_pos, w, h, caption, icon_name, buttons, parent, has_shadow, color_frame, color_body, color_shadow); + initVarHeader(x_pos, y_pos, w, h, caption, icon_name, buttons, parent, shadow_mode, color_frame, color_body, color_shadow); } CComponentsHeaderLocalized::CComponentsHeaderLocalized( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -58,7 +64,7 @@ CComponentsHeaderLocalized::CComponentsHeaderLocalized( const int& x_pos, const const std::string& icon_name, const int& buttons, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) @@ -66,7 +72,7 @@ CComponentsHeaderLocalized::CComponentsHeaderLocalized( const int& x_pos, const g_Locale->getText(caption_locale), icon_name, buttons, parent, - has_shadow, + shadow_mode, color_frame, color_body, color_shadow){}; void CComponentsHeader::initVarHeader( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -74,32 +80,32 @@ void CComponentsHeader::initVarHeader( const int& x_pos, const int& y_pos, const const std::string& icon_name, const int& buttons, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { cc_item_type = CC_ITEMTYPE_FRM_HEADER; - - x = x_pos; - y = y_pos; + cc_txt_save_screen = true; + x = x_old = x_pos; + y = y_old = y_pos; //init header width - width = w == 0 ? frameBuffer->getScreenWidth(true) : w; + width = width_old = w == 0 ? frameBuffer->getScreenWidth(true) : w; //init header default height - height = max(h, g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight()); + height = height_old = max(h, g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight()); cch_size_mode = CC_HEADER_SIZE_LARGE; initCaptionFont(); //sets cch_font and calculate height if required; - shadow = has_shadow; - col_frame = color_frame; - col_body = color_body; - col_shadow = color_shadow; - col_body = COL_MENUHEAD_PLUS_0; - col_body_gradient = g_settings.theme.menu_Head_gradient; - cc_body_gradient_direction = CFrameBuffer::gradientVertical; + shadow = shadow_mode; + col_frame = col_frame_old = color_frame; + col_body = col_body_old = color_body; + col_shadow = col_shadow_old = color_shadow; + col_body = col_body_old = COL_MENUHEAD_PLUS_0; + cc_body_gradient_enable = cc_body_gradient_enable_old = g_settings.theme.menu_Head_gradient; + cc_body_gradient_direction = cc_body_gradient_direction_old = g_settings.theme.menu_Head_gradient_direction; cc_body_gradient_mode = CColorGradient::gradientLight2Dark; cch_text = caption; cch_icon_name = icon_name; @@ -110,15 +116,22 @@ void CComponentsHeader::initVarHeader( const int& x_pos, const int& y_pos, const cch_icon_obj = NULL; cch_text_obj = NULL; cch_btn_obj = NULL; + cch_cl_obj = NULL; cch_col_text = COL_MENUHEAD_TEXT; cch_caption_align = CTextBox::NO_AUTO_LINEBREAK; cch_items_y = CC_CENTERED; cch_offset = 8; cch_icon_x = cch_offset; cch_icon_w = 0; + cch_clock_w = 0; cch_text_x = cch_offset; cch_buttons_space = cch_offset; + cch_cl_enable = false; + cch_cl_format = "%H:%M"; + cch_cl_sec_format = cch_cl_format; + cch_cl_enable_run = false; + addContextButton(buttons); initCCItems(); initParent(parent); @@ -130,16 +143,18 @@ CComponentsHeader::~CComponentsHeader() v_cch_btn.clear(); } -void CComponentsHeader::setCaption(const std::string& caption, const int& align_mode) +void CComponentsHeader::setCaption(const std::string& caption, const int& align_mode, const fb_pixel_t& text_color) { cch_text = caption; cch_caption_align = align_mode; + cch_col_text = text_color; } -void CComponentsHeader::setCaption(neutrino_locale_t caption_locale, const int& align_mode) +void CComponentsHeader::setCaption(neutrino_locale_t caption_locale, const int& align_mode, const fb_pixel_t& text_color) { - cch_text = g_Locale->getText(caption_locale); - cch_caption_align = align_mode; + if (cch_cl_obj) + cch_cl_obj->Stop(); + setCaption(string(g_Locale->getText(caption_locale)), align_mode, text_color); } void CComponentsHeader::setCaptionFont(Font* font) @@ -226,7 +241,7 @@ void CComponentsHeader::initIcon() //global adapt height height = max(height, cch_icon_obj->getHeight()); -// //re-align height of icon object +// //re-assign height of icon object, for the case of changed height // cch_icon_obj->setHeight(height); } } @@ -310,7 +325,7 @@ void CComponentsHeader::initButtons() //set button form properties if (cch_btn_obj){ - cch_btn_obj->setDimensionsAll(0, cch_items_y, 0, 0); + cch_btn_obj->setYPos(cch_items_y); cch_btn_obj->doPaintBg(false); cch_btn_obj->setAppendOffset(cch_buttons_space, 0); cch_btn_obj->removeAllIcons(); @@ -336,6 +351,79 @@ void CComponentsHeader::initButtons() } } + +void CComponentsHeader::enableClock(bool enable, const char* format, const char* sec_format_str, bool run) +{ + cch_cl_enable = enable; + cch_cl_format = format; + if (sec_format_str) + cch_cl_sec_format = sec_format_str; + cch_cl_enable_run = run; + if (!enable){ + if (cch_cl_obj){ + cch_cl_enable_run = false; + removeCCItem(cch_cl_obj); + cch_cl_obj = NULL; + } + } + initCCItems(); +} + + +void CComponentsHeader::disableClock() +{ + enableClock(false, cch_cl_format, cch_cl_sec_format, false); +} + +void CComponentsHeader::initClock() +{ + //exit here if clock was disabled + if (!cch_cl_enable){ + if (cch_cl_obj){ + removeCCItem(cch_cl_obj); + cch_cl_obj = NULL; + } + return; + } + //create instance for header clock object and add to container + if (cch_cl_obj == NULL){ + dprintf(DEBUG_DEBUG, "[CComponentsHeader]\n [%s - %d] init clock...\n", __func__, __LINE__); + cch_cl_obj = new CComponentsFrmClock(0, cch_items_y, cch_font, cch_cl_format, NULL, false, 1, this); + cch_cl_obj->doPaintBg(false); + } + + //set clock form properties + if (cch_cl_obj){ + cch_cl_obj->setYPos(cch_items_y); + cch_cl_obj->setHeight(height); + + //disallow paint of clock, if disabled and exit method + if (!cch_cl_enable){ + cch_cl_obj->allowPaint(false); + cch_cl_obj->Stop(); + return; + } + + //assign time size and format + cch_cl_obj->setClockFont(cch_font); + cch_cl_obj->setClockFormat(cch_cl_format, cch_cl_sec_format); + + //set corner mode of button item + int cc_btn_corner_type = corner_type; + if (corner_type == CORNER_TOP_RIGHT || corner_type == CORNER_TOP) + cc_btn_corner_type = CORNER_TOP_RIGHT; + else + cc_btn_corner_type = CORNER_RIGHT; + cch_cl_obj->setCorner(corner_rad-fr_thickness, cc_btn_corner_type); + + //global adapt height + height = max(height, cch_cl_obj->getHeight()); + + //re-assign height of clock object, for the case of changed height + cch_cl_obj->setHeight(height); + } +} + void CComponentsHeader::initCaption() { //recalc header text position if header icon is defined @@ -346,42 +434,76 @@ void CComponentsHeader::initCaption() //calc width of text object in header cc_text_w = width-cch_text_x-cch_offset; + + //context buttons int buttons_w = 0; if (cch_btn_obj){ //get width of buttons object - buttons_w = cch_btn_obj->getWidth(); + buttons_w = cch_btn_obj->empty() ? 0 : cch_btn_obj->getWidth(); + dprintf(DEBUG_DEBUG, "[CComponentsHeader]\n [%s - %d] init context buttons...x=%d, y=%d, width=%d, height=%d\n", __func__, __LINE__, cch_btn_obj->getXPos(), cch_btn_obj->getYPos(), cch_btn_obj->getWidth(), cch_btn_obj->getHeight()); //set x position of buttons cch_btn_obj->setXPos(width - buttons_w); + + //set required width of caption object + cc_text_w -= (buttons_w + cch_offset); } - //set required width of caption object - cc_text_w -= buttons_w-cch_offset; + + //clock + if (cch_cl_obj){ + //refresh clock properties + cch_cl_obj->refresh(); + + //get width of clock object + int clock_w = cch_cl_enable ? cch_cl_obj->getWidth() : 0; + + //set x position of clock + cch_cl_obj->setXPos(width - buttons_w - clock_w - cch_offset); + + //set required width of caption object + cc_text_w -= (clock_w + cch_offset); + + //stop clock if disabled or option run is disabled and clock is running + if (cch_cl_enable){ + if (!cch_cl_enable_run && cch_cl_obj->isRun()){ + cch_cl_obj->Stop(); + cch_cl_obj->allowPaint(false); + } + } + + //clock visible or not visible if run or not + cch_cl_obj->allowPaint(cch_cl_enable); + } + //create cch_text_obj and add to collection if (cch_text_obj == NULL){ dprintf(DEBUG_DEBUG, "[CComponentsHeader]\n [%s - %d] init header text: %s [ x %d w %d ]\n", __func__, __LINE__, cch_text.c_str(), cch_text_x, cc_text_w); - cch_text_obj = new CComponentsText(); + cch_text_obj = new CComponentsText(this); + cch_text_obj->doPaintBg(false); } - //add text item - if (!cch_text_obj->isAdded()) - addCCItem(cch_text_obj); //text - //set header text properties if (cch_text_obj){ - //set alignment of text item in dependency from text alignment + //set alignment of text item in dependency from text alignment if (cch_caption_align == CTextBox::CENTER) cch_text_x = CC_CENTERED; + + //assign general properties cch_text_obj->setDimensionsAll(cch_text_x, cch_items_y, cc_text_w, height); - cch_text_obj->doPaintBg(false); - cch_text_obj->setText(cch_text, cch_caption_align, cch_font); - cch_text_obj->forceTextPaint(); //here required - cch_text_obj->setTextColor(cch_col_text); cch_text_obj->setColorBody(col_body); - cch_text_obj->enableTboxSaveScreen(save_tbox_screen); + if (cc_body_gradient_enable != cc_body_gradient_enable_old) + cch_text_obj->getCTextBoxObject()->clearScreenBuffer(); + cch_text_obj->setTextColor(cch_col_text); + cch_text_obj->setText(cch_text, cch_caption_align, cch_font); + cch_text_obj->enableTboxSaveScreen(cc_body_gradient_enable || cc_txt_save_screen); //corner of text item cch_text_obj->setCorner(corner_rad-fr_thickness, corner_type); + //synchronize clock color with caption color + if (cch_cl_obj) + cch_cl_obj->setTextColor(cch_col_text); + /* global adapt height not needed here again because this object is initialized at last @@ -392,6 +514,9 @@ void CComponentsHeader::initCaption() void CComponentsHeader::initCCItems() { + //set basic properties + Init(x, y, width, height, col_frame, col_body, col_shadow); + //set size initCaptionFont(); @@ -401,6 +526,9 @@ void CComponentsHeader::initCCItems() //init buttons initButtons(); + //init clock + initClock(); + //init text initCaption(); } @@ -412,4 +540,22 @@ void CComponentsHeader::paint(bool do_save_bg) //paint form contents paintForm(do_save_bg); + + //start clock if enabled + if (cch_cl_obj){ + if (cch_cl_enable && cch_cl_enable_run) + cch_cl_obj->Start(); + } } + + +bool CComponentsHeader::enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color, const int& direction) +{ + int dir = direction == -1 ? g_settings.theme.menu_Head_gradient_direction : direction; //header mode is pre defined here + + if (cch_text_obj->getCTextBoxObject()) + cch_text_obj->getCTextBoxObject()->clearScreenBuffer(); + + return CComponentsForm::enableColBodyGradient(enable_mode, sec_color, dir); +} + diff --git a/src/gui/components/cc_frm_header.h b/src/gui/components/cc_frm_header.h index a55154660..56eb3e38d 100644 --- a/src/gui/components/cc_frm_header.h +++ b/src/gui/components/cc_frm_header.h @@ -29,13 +29,14 @@ #include "cc_item_picture.h" #include "cc_item_text.h" #include "cc_frm_icons.h" +#include "cc_frm_clock.h" #include //! Sub class of CComponentsForm. Shows a header with prepared items. /*! CComponentsHeader provides prepared items like icon, caption and context button icons, mostly for usage in menues or simple windows */ -class CComponentsHeader : public CComponentsForm +class CComponentsHeader : public CComponentsForm, public CCTextScreen { private: ///member: init genaral variables, parameters for mostly used properties @@ -44,7 +45,7 @@ class CComponentsHeader : public CComponentsForm const std::string& = "", const int& buttons = 0, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -56,6 +57,8 @@ class CComponentsHeader : public CComponentsForm CComponentsText * cch_text_obj; ///object: context button object, see also addContextButton(), removeContextButtons() CComponentsIconForm * cch_btn_obj; + ///object: clock object + CComponentsFrmClock * cch_cl_obj; ///property: caption text, see also setCaption() std::string cch_text; @@ -72,6 +75,8 @@ class CComponentsHeader : public CComponentsForm int cch_icon_x; ///property: internal width for icon object int cch_icon_w; + ///property: internal width for clock object + int cch_clock_w; ///property: internal x-position for caption object int cch_text_x; ///property: internal offset of context button icons within context button object @@ -84,6 +89,14 @@ class CComponentsHeader : public CComponentsForm int cch_size_mode; ///property: alignment of caption within header, see also setCaptionAlignment(), possible values are CTextBox::CENTER, default = CTextBox::NO_AUTO_LINEBREAK (left) int cch_caption_align; + ///property: enable/disable of clock, see also enableClock() + bool cch_cl_enable; + ///property: clock format + const char* cch_cl_format; + ///property: secondary clock format + const char* cch_cl_sec_format; + ///property: enable running clock + bool cch_cl_enable_run; ///init font object and recalculates height if required void initCaptionFont(Font* font = NULL); @@ -93,6 +106,8 @@ class CComponentsHeader : public CComponentsForm void initCaption(); ///sub: init context button object void initButtons(); + ///sub: init clock object + void initClock(); public: enum @@ -108,7 +123,7 @@ class CComponentsHeader : public CComponentsForm const std::string& = "", const int& buttons = 0, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -116,9 +131,9 @@ class CComponentsHeader : public CComponentsForm virtual ~CComponentsHeader(); ///set caption text, parameters: string, int align_mode (default left) - virtual void setCaption(const std::string& caption, const int& align_mode = CTextBox::NO_AUTO_LINEBREAK); + virtual void setCaption(const std::string& caption, const int& align_mode = CTextBox::NO_AUTO_LINEBREAK, const fb_pixel_t& text_color = COL_MENUHEAD_TEXT); ///set caption text, parameters: loacle, int align_mode (default left) - virtual void setCaption(neutrino_locale_t caption_locale, const int& align_mode = CTextBox::NO_AUTO_LINEBREAK); + virtual void setCaption(neutrino_locale_t caption_locale, const int& align_mode = CTextBox::NO_AUTO_LINEBREAK, const fb_pixel_t& text_color = COL_MENUHEAD_TEXT); ///set alignment of caption within header, possible paramters are CTextBox::CENTER, CTextBox::NO_AUTO_LINEBREAK virtual void setCaptionAlignment(const int& align_mode){cch_caption_align = align_mode;}; @@ -181,7 +196,7 @@ class CComponentsHeader : public CComponentsForm }; ///set offset between icons within context button object - virtual void setButtonsSpace(const int buttons_space){cch_buttons_space = buttons_space;}; + virtual void setButtonsSpace(const int buttons_space){cch_buttons_space = buttons_space;} enum { @@ -189,15 +204,31 @@ class CComponentsHeader : public CComponentsForm CC_HEADER_SIZE_SMALL = 1 }; ///set size of header, possible values are CC_HEADER_SIZE_LARGE, CC_HEADER_SIZE_SMALL - virtual void setSizeMode(const int& size_mode){cch_size_mode = size_mode; initCCItems();}; + virtual void setSizeMode(const int& size_mode){cch_size_mode = size_mode; initCCItems();} ///init all items within header object virtual void initCCItems(); ///returns the text object - virtual CComponentsText* getTextObject(){return cch_text_obj;}; + virtual CComponentsText* getTextObject(){return cch_text_obj;} + + ///returns the clock object + virtual CComponentsFrmClock* getClockObject(){return cch_cl_obj;} + + ///enable display of clock, parameter bool enable, const char* format, bool run + virtual void enableClock(bool enable = true, const char* format = "%H:%M", const char* sec_format_str = NULL, bool run = false); + ///disable clock, without parameter + virtual void disableClock(); ///paint header virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); + + ///hides item, arg: no_restore see hideCCItem() + void hide(){disableClock(); CComponents::hide();} + ///erase current screen without restore of background, it's similar to paintBackgroundBoxRel() from CFrameBuffer + virtual void kill(){disableClock(); CComponentsForm::kill();} + + ///set color gradient on/off, returns true if gradient mode was changed + virtual bool enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color = 255 /*=COL_BACKGROUND*/, const int& direction = -1); }; //! Sub class of CComponentsHeader. @@ -213,7 +244,7 @@ class CComponentsHeaderLocalized : public CComponentsHeader const std::string& = "", const int& buttons = 0, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); diff --git a/src/gui/components/cc_frm_icons.cpp b/src/gui/components/cc_frm_icons.cpp index 6cb020cc2..e7e47a860 100644 --- a/src/gui/components/cc_frm_icons.cpp +++ b/src/gui/components/cc_frm_icons.cpp @@ -41,16 +41,16 @@ CComponentsIconForm::CComponentsIconForm(CComponentsForm* parent) CComponentsIconForm::CComponentsIconForm( const int &x_pos, const int &y_pos, const int &w, const int &h, const std::vector &v_icon_names, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { - initVarIconForm(x_pos, y_pos, w, h, v_icon_names, parent, has_shadow, color_frame, color_body, color_shadow); + initVarIconForm(x_pos, y_pos, w, h, v_icon_names, parent, shadow_mode, color_frame, color_body, color_shadow); } void CComponentsIconForm::initVarIconForm( const int &x_pos, const int &y_pos, const int &w, const int &h, const std::vector &v_icon_names, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { cc_item_type = CC_ITEMTYPE_FRM_ICONFORM; @@ -60,7 +60,7 @@ void CComponentsIconForm::initVarIconForm( const int &x_pos, const int &y_pos, c width = w; height = h; v_icons = v_icon_names; - shadow = has_shadow; + shadow = shadow_mode; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; diff --git a/src/gui/components/cc_frm_icons.h b/src/gui/components/cc_frm_icons.h index 302294800..c48fdd3ca 100644 --- a/src/gui/components/cc_frm_icons.h +++ b/src/gui/components/cc_frm_icons.h @@ -36,7 +36,7 @@ class CComponentsIconForm : public CComponentsFrmChain void initVarIconForm( const int &x_pos, const int &y_pos, const int &w, const int &h, const std::vector &v_icon_names, CComponentsForm* parent, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -46,7 +46,7 @@ class CComponentsIconForm : public CComponentsFrmChain CComponentsIconForm( const int &x_pos, const int &y_pos, const int &w, const int &h, const std::vector &v_icon_names, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); // ~CComponentsIconForm(); //inherited from CComponentsForm diff --git a/src/gui/components/cc_frm_scrollbar.cpp b/src/gui/components/cc_frm_scrollbar.cpp index 464c50388..51cc88594 100644 --- a/src/gui/components/cc_frm_scrollbar.cpp +++ b/src/gui/components/cc_frm_scrollbar.cpp @@ -62,9 +62,9 @@ using namespace std; CComponentsScrollBar::CComponentsScrollBar( const int &x_pos, const int &y_pos, const int &w, const int &h, const int& count, CComponentsForm* parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) - :CComponentsFrmChain(x_pos, y_pos, w, h, NULL, CC_DIR_Y, parent, has_shadow, color_frame, color_body, color_shadow) + :CComponentsFrmChain(x_pos, y_pos, w, h, NULL, CC_DIR_Y, parent, shadow_mode, color_frame, color_body, color_shadow) { initVarSbForm(count); } @@ -165,12 +165,12 @@ void CComponentsScrollBar::initSegments() //set color for marked id if (sb_mark_id == id){ item->setColorBody(COL_MENUCONTENTSELECTED_PLUS_0); - item->enableColBodyGradient(true); + item->enableColBodyGradient(CC_COLGRAD_COL_A_2_COL_B); item->setColBodyGradient(CColorGradient::gradientDark2Light2Dark, CFrameBuffer::gradientHorizontal); } else{ item->setColorBody(COL_MENUCONTENT_PLUS_1); - item->enableColBodyGradient(false); + item->disableColBodyGradient(); } } diff --git a/src/gui/components/cc_frm_scrollbar.h b/src/gui/components/cc_frm_scrollbar.h index 55b93faaa..fdf26a308 100644 --- a/src/gui/components/cc_frm_scrollbar.h +++ b/src/gui/components/cc_frm_scrollbar.h @@ -63,7 +63,7 @@ class CComponentsScrollBar : public CComponentsFrmChain CComponentsScrollBar( const int &x_pos, const int &y_pos, const int &w = 15, const int &h = 40, const int& count = 1, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_3, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); // ~CComponentsScrollBar(); //inherited from CComponentsForm diff --git a/src/gui/components/cc_frm_signalbars.cpp b/src/gui/components/cc_frm_signalbars.cpp index 8af1782a0..d361216ac 100644 --- a/src/gui/components/cc_frm_signalbars.cpp +++ b/src/gui/components/cc_frm_signalbars.cpp @@ -143,6 +143,8 @@ void CSignalBar::initSBarValue() if (sb_vlbl == NULL){ sb_vlbl = new CComponentsLabel(); sb_vlbl->doPaintBg(false); + sb_vlbl->doPaintTextBoxBg(false); + sb_vlbl->enableTboxSaveScreen(true); sb_vlbl->setText(" 0%", sb_val_mode, sb_font); } @@ -150,7 +152,7 @@ void CSignalBar::initSBarValue() int vlbl_x = sb_scale->getXPos() + sb_scale_width + append_y_offset; int vlbl_h = sb_scale->getHeight(); int vlbl_y = sb_item_height/2 + sb_item_top - vlbl_h/2 - append_x_offset; - sb_vlbl->setDimensionsAll(vlbl_x, vlbl_y, sb_vlbl_width, vlbl_h); + sb_vlbl->setDimensionsAll(vlbl_x, vlbl_y, sb_vlbl_width - append_x_offset, vlbl_h); //set current text and body color color sb_vlbl->setTextColor(sb_caption_color); @@ -167,21 +169,22 @@ void CSignalBar::initSBarName() if (sb_lbl == NULL){ sb_lbl = new CComponentsLabel(); sb_lbl->doPaintBg(false); + sb_lbl->doPaintTextBoxBg(false); + sb_lbl->enableTboxSaveScreen(true); sb_lbl->setText(sb_name, CTextBox::NO_AUTO_LINEBREAK | CTextBox::RIGHT, sb_font); - sb_lbl->forceTextPaint(); - sb_lbl->doPaintTextBoxBg(true); } //move and set dimensions int lbl_x = sb_vlbl->getXPos()+ sb_vlbl->getWidth(); int lbl_h = sb_vlbl->getHeight(); int lbl_y = sb_item_height/2 + sb_item_top - lbl_h/2 - append_x_offset; - sb_lbl->setDimensionsAll(lbl_x, lbl_y, sb_lbl_width, lbl_h); + sb_lbl->setDimensionsAll(lbl_x, lbl_y, sb_lbl_width- append_x_offset, lbl_h); //set current text and body color sb_lbl->setTextColor(sb_caption_color); sb_lbl->setColorBody(col_body); + //add name label object to container if (!sb_lbl->isAdded()) addCCItem(sb_lbl); @@ -218,12 +221,6 @@ void CSignalBar::paintScale() percent += "%"; sb_vlbl->setText(percent, sb_val_mode, sb_font); - //we must force paint backround, because of changing values - sb_vlbl->doPaintBg(true); - sb_vlbl->forceTextPaint(); - sb_vlbl->doPaintTextBoxBg(true); - sb_vlbl->setColorBody(col_body); - //repaint labels for(size_t i=0; iv_cc_items.size(); i++) v_cc_items[i]->paint(false); diff --git a/src/gui/components/cc_frm_slider.cpp b/src/gui/components/cc_frm_slider.cpp index e96d83c07..e697f24ba 100644 --- a/src/gui/components/cc_frm_slider.cpp +++ b/src/gui/components/cc_frm_slider.cpp @@ -34,7 +34,7 @@ CComponentsSlider::CComponentsSlider( const int& x_pos, const int& y_pos, const const int& min_value, const int& max_value, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t& color_frame, fb_pixel_t& color_body, fb_pixel_t& color_shadow) @@ -51,7 +51,7 @@ CComponentsSlider::CComponentsSlider( const int& x_pos, const int& y_pos, const csl_min_value = min_value; csl_max_value = max_value; - shadow = has_shadow; + shadow = shadow_mode; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; @@ -88,8 +88,9 @@ void CComponentsSlider::initCCSlBody() { if (!csl_body_icon.empty()){ if (csl_body_obj == NULL){ - csl_body_obj = new CComponentsPicture(0, 0, 0, 0, csl_body_icon); - csl_body_obj->doPaintBg(false); + csl_body_obj = new CComponentsPicture(0, 0, width-2*fr_thickness, 16, csl_body_icon); + csl_body_obj->setColorBody(this->col_body); //FIXME: Background handling during current instance of slider object + csl_body_obj->doPaintBg(true); addCCItem(csl_body_obj); } else @@ -118,8 +119,9 @@ void CComponentsSlider::initCCSlSlider() { if (!csl_slider_icon.empty()){ if (csl_slider_obj == NULL){ - csl_slider_obj = new CComponentsPicture(0, 0, 0, 0, csl_slider_icon); - csl_slider_obj->doPaintBg(false); + csl_slider_obj = new CComponentsPicture(0, 0, csl_slider_icon); + csl_slider_obj->setColorBody(this->col_body); //FIXME: Background handling during current instance of slider object + csl_slider_obj->doPaintBg(true); addCCItem(csl_slider_obj); } else @@ -135,7 +137,7 @@ void CComponentsSlider::initCCSlSlider() int slider_h = csl_slider_obj->getHeight(); //position of slider icon - int slider_x = csl_body_obj->getXPos() - slider_w/2 + csl_body_obj->getWidth() * (abs(csl_min_value) + csl_current_value) / (abs(csl_min_value) + abs(csl_max_value)); + int slider_x = csl_body_obj->getXPos() + (csl_body_obj->getWidth()-slider_w) * (abs(csl_min_value) + csl_current_value) / (abs(csl_min_value) + abs(csl_max_value)); int slider_y = height/2-slider_h/2; if (csl_slider_obj) diff --git a/src/gui/components/cc_frm_slider.h b/src/gui/components/cc_frm_slider.h index 08395d759..97e5d7e98 100644 --- a/src/gui/components/cc_frm_slider.h +++ b/src/gui/components/cc_frm_slider.h @@ -66,7 +66,7 @@ class CComponentsSlider : public CComponentsForm const int& min_value = 0, const int& max_value = 100, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t& color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t& color_body = COL_MENUHEAD_PLUS_0, fb_pixel_t& color_shadow = COL_MENUCONTENTDARK_PLUS_0); diff --git a/src/gui/components/cc_frm_window.cpp b/src/gui/components/cc_frm_window.cpp index 07f2b67a5..4be33a44a 100644 --- a/src/gui/components/cc_frm_window.cpp +++ b/src/gui/components/cc_frm_window.cpp @@ -66,53 +66,53 @@ CComponentsWindow::CComponentsWindow( const int& x_pos, const int& y_pos, const neutrino_locale_t locale_caption, const string& iconname, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { string s_caption = locale_caption != NONEXISTANT_LOCALE ? g_Locale->getText(locale_caption) : ""; - initVarWindow(x_pos, y_pos, w, h, s_caption, iconname, parent, has_shadow, color_frame, color_body, color_shadow); + initVarWindow(x_pos, y_pos, w, h, s_caption, iconname, parent, shadow_mode, color_frame, color_body, color_shadow); } CComponentsWindow::CComponentsWindow( const int& x_pos, const int& y_pos, const int& w, const int& h, const string& caption, const string& iconname, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { - initVarWindow(x_pos, y_pos, w, h, caption, iconname, parent, has_shadow, color_frame, color_body, color_shadow); + initVarWindow(x_pos, y_pos, w, h, caption, iconname, parent, shadow_mode, color_frame, color_body, color_shadow); } CComponentsWindowMax::CComponentsWindowMax( const string& caption, const string& iconname, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) :CComponentsWindow(0, 0, 0, 0, caption, - iconname, parent, has_shadow, color_frame, color_body, color_shadow){}; + iconname, parent, shadow_mode, color_frame, color_body, color_shadow){}; CComponentsWindowMax::CComponentsWindowMax( neutrino_locale_t locale_caption, const string& iconname, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) :CComponentsWindow(0, 0, 0, 0, locale_caption != NONEXISTANT_LOCALE ? g_Locale->getText(locale_caption) : "", - iconname, parent, has_shadow, color_frame, color_body, color_shadow){}; + iconname, parent, shadow_mode, color_frame, color_body, color_shadow){}; void CComponentsWindow::initVarWindow( const int& x_pos, const int& y_pos, const int& w, const int& h, const string& caption, const string& iconname, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) @@ -134,7 +134,7 @@ void CComponentsWindow::initVarWindow( const int& x_pos, const int& y_pos, const dprintf(DEBUG_DEBUG, "[CComponentsWindow] [%s - %d] icon name = %s\n", __func__, __LINE__, ccw_icon_name.c_str()); - shadow = has_shadow; + shadow = shadow_mode; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; @@ -212,7 +212,7 @@ void CComponentsWindow::initFooter() if (ccw_footer){ ccw_footer->setPos(0, CC_APPEND); ccw_footer->setWidth(width-2*fr_thickness); - ccw_footer->setShadowOnOff(shadow); + ccw_footer->enableShadow(shadow); ccw_footer->setCorner(corner_rad, CORNER_BOTTOM); } } diff --git a/src/gui/components/cc_frm_window.h b/src/gui/components/cc_frm_window.h index 79b0c9433..2ef5351fc 100644 --- a/src/gui/components/cc_frm_window.h +++ b/src/gui/components/cc_frm_window.h @@ -101,7 +101,7 @@ class CComponentsWindow : public CComponentsForm const std::string& caption = "", const std::string& iconname = "", CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -126,7 +126,7 @@ class CComponentsWindow : public CComponentsForm const std::string& caption = "", const std::string& iconname = "", CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -136,7 +136,7 @@ class CComponentsWindow : public CComponentsForm neutrino_locale_t locale_text = NONEXISTANT_LOCALE, const std::string& iconname = "", CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -214,7 +214,7 @@ class CComponentsWindowMax : public CComponentsWindow ///simple constructor for CComponentsWindow, provides parameters for caption as string and icon, this shows a centered window based up current screen settings CComponentsWindowMax( const std::string& caption, const std::string& iconname = "", CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); @@ -222,7 +222,7 @@ class CComponentsWindowMax : public CComponentsWindow ///simple constructor for CComponentsWindow, provides parameters for caption from locales and icon, this shows a centered window based up current screen settings CComponentsWindowMax( neutrino_locale_t locale_caption, const std::string& iconname = "", CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); diff --git a/src/gui/components/cc_item.cpp b/src/gui/components/cc_item.cpp index 2c2b158e0..4f9b242c4 100644 --- a/src/gui/components/cc_item.cpp +++ b/src/gui/components/cc_item.cpp @@ -3,7 +3,7 @@ Copyright (C) 2001 by Steffen Hehn 'McClean' Classes for generic GUI-related components. - Copyright (C) 2012-2014, Thilo Graf 'dbt' + Copyright (C) 2012-2015, Thilo Graf 'dbt' Copyright (C) 2012, Michael Liebmann 'micha-bbg' License: GPL @@ -18,10 +18,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - Boston, MA 02110-1301, USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H @@ -30,7 +28,7 @@ #include #include -#include "cc_base.h" +#include "cc_item.h" #include #include #include @@ -46,19 +44,12 @@ using namespace std; //abstract sub class CComponentsItem from CComponents CComponentsItem::CComponentsItem(CComponentsForm* parent) { - cc_item_type = CC_ITEMTYPE_BASE; + cc_item_type = CC_ITEMTYPE_GENERIC; cc_item_index = CC_NO_INDEX; cc_item_enabled = true; cc_item_selected = false; cc_page_number = 0; cc_has_focus = true; - cc_gradientData.gradientBuf = NULL; - cc_body_gradient_mode = CColorGradient::gradientLight2Dark; - cc_body_gradient_intensity = CColorGradient::light; - cc_body_gradient_intensity_v_min = 0x40; - cc_body_gradient_intensity_v_max = 0xE0; - cc_body_gradient_saturation = 0xC0; - cc_body_gradient_direction = CFrameBuffer::gradientVertical; initParent(parent); } @@ -69,86 +60,70 @@ void CComponentsItem::initParent(CComponentsForm* parent) cc_parent->addCCItem(this); } -// Paint container background in cc-items with shadow, background and frame. +// init container properties in cc-items for shadow, background and frame. // This member must be called first in all paint() members before paint other items into the container. // If backround is not required, it's possible to override this with variable paint_bg=false, use doPaintBg(true/false) to set this! void CComponentsItem::paintInit(bool do_save_bg) { - //init color gradient - if (col_body_gradient) - initBodyGradient(); + if (hasChanges()) + clearFbData(); - clearFbData(); + if (v_fbdata.empty()){ + int th = fr_thickness; + fb_pixel_t col_frame_cur = col_frame; - int th = fr_thickness; - fb_pixel_t col_frame_cur = col_frame; + //calculate current needed frame thickeness and color, if item selected or not + if (cc_item_selected){ + col_frame_cur = col_frame_sel; + th = max(fr_thickness_sel, fr_thickness); + } - //calculate current needed frame thickeness and color, if item selected or not - if (cc_item_selected){ - col_frame_cur = col_frame_sel; - th = max(fr_thickness_sel, fr_thickness); + //calculate current needed corner radius for body box, depends of frame thickness + int rad = (corner_rad>th) ? corner_rad-th : corner_rad; + int sw = (shadow) ? shadow_w : 0; + + //evaluate shadow mode + bool sh_r = (shadow & CC_SHADOW_ON) || (shadow & CC_SHADOW_RIGHT); + bool sh_b = (shadow & CC_SHADOW_ON) || (shadow & CC_SHADOW_BOTTOM); + + //if item is bound on a parent form, we must use real x/y values and from parent form as reference + int ix = x, iy = y; + if (cc_parent){ + ix = cc_xr; + iy = cc_yr; + } + + //handle shadow width + if (width <= sw || height <= sw){ //don't use shadow, if item dimensions too small + dprintf(DEBUG_NORMAL, "\033[33m[CComponentsItem]\t[%s - %d] shadow dimensions too small sw=%d, shadow is disabled set dimension to 0\033[0m\n",__func__, __LINE__, sw); + shadow = CC_SHADOW_OFF; + sw = 0; + } + int isw = sw*2; + int ixsr = ix + width - isw/2; + int iysb = iy + height - isw/2; + + //init paint layers + cc_fbdata_t fbdata[] = + { + {true, CC_FBDATA_TYPE_BGSCREEN, ix, iy, width+isw/2, height+isw/2, 0, 0, 0, 0, NULL, NULL, NULL, false}, //buffered bg + {sh_r, CC_FBDATA_TYPE_SHADOW_BOX, ixsr, iy+isw/2, isw, height, col_shadow, corner_rad, corner_type & CORNER_RIGHT, 0, NULL, NULL, NULL, false}, //shadow right + {sh_b, CC_FBDATA_TYPE_SHADOW_BOX, ix+isw/2, iysb, width, isw, col_shadow, corner_rad, corner_type & CORNER_BOTTOM, 0, NULL, NULL, NULL, false}, //shadow bottom + {true, CC_FBDATA_TYPE_FRAME, ix, iy, width, height, col_frame_cur, corner_rad, corner_type, th, NULL, NULL, NULL, false}, //frame + {true, CC_FBDATA_TYPE_BOX, ix+th, iy+th, width-2*th, height-2*th, col_body, rad, corner_type, 0, NULL, NULL, NULL, false}, //body + }; + + for(size_t i =0; i< (sizeof(fbdata) / sizeof(fbdata[0])) ;i++) { + if ((fbdata[i].fbdata_type == CC_FBDATA_TYPE_FRAME) && !fr_thickness) + continue; + v_fbdata.push_back(fbdata[i]); + } + + dprintf(DEBUG_DEBUG, "[CComponentsItem] %s:\ncc_item_type: %d\ncc_item_index = %d\nheight = %d\nwidth = %d\n", __func__, cc_item_type, cc_item_index, height, width); } - - //calculate current needed corner radius for body box, depends of frame thickness - int rad = (corner_rad>th) ? corner_rad-th : corner_rad; - int sw = (shadow) ? shadow_w : 0; - - //if item is bound on a parent form, we must use real x/y values and from parent form as reference - int ix = x, iy = y; - if (cc_parent){ - ix = cc_xr; - iy = cc_yr; - } - - cc_gradientData.mode = CFrameBuffer::pbrg_noFree; - void* gradientData = (cc_gradientData.gradientBuf == NULL) ? NULL : &cc_gradientData; - comp_fbdata_t fbdata[] = - { - {CC_FBDATA_TYPE_BGSCREEN, ix, iy, width+sw, height+sw, 0, 0, 0, NULL, NULL}, - {CC_FBDATA_TYPE_SHADOW_BOX, ix+sw, iy+sw, width, height, col_shadow, corner_rad, 0, NULL, NULL},//shadow - {CC_FBDATA_TYPE_FRAME, ix, iy, width, height, col_frame_cur, corner_rad, th, NULL, NULL},//frame - {CC_FBDATA_TYPE_BOX, ix+th, iy+th, width-2*th, height-2*th, col_body, rad, 0, NULL, gradientData},//body - }; - - for(size_t i =0; i< (sizeof(fbdata) / sizeof(fbdata[0])) ;i++) { - if (((fbdata[i].fbdata_type == CC_FBDATA_TYPE_SHADOW_BOX) && !shadow) || - ((fbdata[i].fbdata_type == CC_FBDATA_TYPE_FRAME) && !fr_thickness)) - continue; - v_fbdata.push_back(fbdata[i]); - } - - dprintf(DEBUG_DEBUG, "[CComponentsItem] %s:\ncc_item_type: %d\ncc_item_index = %d\nheight = %d\nwidth = %d\n", __func__, cc_item_type, cc_item_index, height, width); - paintFbItems(do_save_bg); } -//restore last saved screen behind form box, -//Do use parameter 'no restore' to override the restore funtionality. -//For embedded items is it mostly not required to restore saved screens, so no_resore=true also is default parameter -//for such items. -//This member ensures demage of already existing screen buffer too, if parameter no_restore was changed while runtime. -void CComponentsItem::hideCCItem(bool no_restore) -{ - //restore saved screen if available - if (saved_screen.pixbuf) { - frameBuffer->waitForIdle("CComponentsItem::hideCCItem()"); - frameBuffer->RestoreScreen(saved_screen.x, saved_screen.y, saved_screen.dx, saved_screen.dy, saved_screen.pixbuf); - - if (no_restore) { //on parameter no restore=true delete saved screen if available - delete[] saved_screen.pixbuf; - saved_screen.pixbuf = NULL; - firstPaint = true; - } - } - - is_painted = false; -} - -void CComponentsItem::hide(bool no_restore) -{ - hideCCItem(no_restore); -} - //erase or paint over rendered objects void CComponentsItem::kill(const fb_pixel_t& bg_color, bool ignore_parent) { @@ -194,20 +169,6 @@ bool CComponentsItem::isAdded() return false; } -inline void CComponentsItem::setXPos(const int& xpos) -{ - x = xpos; - if (cc_parent) - setRealXPos(cc_parent->getRealXPos() + x); -} - -inline void CComponentsItem::setYPos(const int& ypos) -{ - y = ypos; - if (cc_parent) - setRealYPos(cc_parent->getRealYPos() + y); -} - void CComponentsItem::setXPosP(const uint8_t& xpos_percent) { int x_tmp = cc_parent ? xpos_percent*cc_parent->getWidth() : xpos_percent*frameBuffer->getScreenWidth(); @@ -254,28 +215,3 @@ void CComponentsItem::setFocus(bool focus) } cc_has_focus = focus; } - -void CComponentsItem::initBodyGradient() -{ - if (col_body_gradient && cc_gradientData.gradientBuf && (old_gradient_color != col_body || old_gradient_c2c != g_settings.theme.gradient_c2c)) { - free(cc_gradientData.gradientBuf); - cc_gradientData.gradientBuf = NULL; - if (cc_gradientData.boxBuf) { - cs_free_uncached(cc_gradientData.boxBuf); - cc_gradientData.boxBuf = NULL; - } - } - if (cc_gradientData.gradientBuf == NULL) { - CColorGradient ccGradient; - int gsize = cc_body_gradient_direction == CFrameBuffer::gradientVertical ? height : width; - if (g_settings.theme.gradient_c2c) - cc_gradientData.gradientBuf = ccGradient.gradientColorToColor(col_body, cc_body_gradient_2nd_col, NULL, gsize, cc_body_gradient_mode, cc_body_gradient_intensity); - else - cc_gradientData.gradientBuf = ccGradient.gradientOneColor(col_body, NULL, gsize, cc_body_gradient_mode, cc_body_gradient_intensity, cc_body_gradient_intensity_v_min, cc_body_gradient_intensity_v_max, cc_body_gradient_saturation); - old_gradient_color = col_body; - old_gradient_c2c = g_settings.theme.gradient_c2c; - } - - cc_gradientData.direction = cc_body_gradient_direction; - cc_gradientData.mode = CFrameBuffer::pbrg_noOption; -} diff --git a/src/gui/components/cc_item.h b/src/gui/components/cc_item.h new file mode 100644 index 000000000..a3a713429 --- /dev/null +++ b/src/gui/components/cc_item.h @@ -0,0 +1,129 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2012-2015, Thilo Graf 'dbt' + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __CC_ITEMS__ +#define __CC_ITEMS__ + +#include "cc_types.h" +#include "cc_base.h" +#include "cc_draw.h" +#include +#include +#include + +class CComponentsItem : public CComponents +{ + protected: + ///property: define of item index, all bound items get an index, + ///default: CC_NO_INDEX as identifer for not embedded item and default index=0 for form as main parent + ///see also getIndex(), setIndex() + int cc_item_index; + ///property: define of item type, see cc_types.h for possible types + int cc_item_type; + ///property: default enabled + bool cc_item_enabled; + ///property: default not selected + bool cc_item_selected; + ///property: page number, this defines current item page location, means: this item is embedded in a parent container on page number n, see also setPageNumber() + ///default value is 0 for page one, any value > 0 causes handling for mutilple pages at parent container + uint8_t cc_page_number; + ///specifies that some certain operations especially eg. exec events for that item are possible, see also setFocus(), hasFocus() + bool cc_has_focus; + + ///Pointer to the form object in which this item is embedded. + ///Is typically the type CComponentsForm or derived classes, default intialized with NULL + CComponentsForm *cc_parent; + + ///initialze of basic framebuffer elements with shadow, background and frame. + ///must be called first in all paint() members before paint any item, + ///If backround is not required, it's possible to override this with variable paint_bg=false, use doPaintBg(true/false) to set this! + ///arg do_save_bg=false avoids using of unnecessary pixel memory, eg. if no hide with restore is provided. This is mostly the case whenever + ///an item will be hide or overpainted with other methods, or it's embedded (bound) in a parent form. + void paintInit(bool do_save_bg); + + ///add "this" current item to parent + void initParent(CComponentsForm* parent); + + + public: + CComponentsItem(CComponentsForm *parent = NULL); + + ///sets pointer to the form object in which this item is embedded. + virtual void setParent(CComponentsForm *parent){cc_parent = parent;}; + ///returns pointer to the form object in which this item is embedded. + virtual CComponentsForm* getParent(){return cc_parent;}; + ///property: returns true if item is added to a form + virtual bool isAdded(); + ///indicates wether item has focus + virtual bool hasFocus(){return cc_has_focus;} + ///set or unset focus of item, stand alone items without parent have always set focus to true, inside of a parent form object, always the last added item has focus + virtual void setFocus(bool focus); + + ///erase or paint over rendered objects without restore of background, it's similar to paintBackgroundBoxRel() known + ///from CFrameBuffer but with possiblity to define color, default color is 0 (empty background) + ///NOTE: Items with parent binding use the parent background color as default! Set parameter 'ignore_parent=true' to ignore parent background color! + virtual void kill(const fb_pixel_t& bg_color = COL_BACKGROUND_PLUS_0, bool ignore_parent = false); + + ///get the current item type, see attribute cc_item_type above + virtual int getItemType(); + ///syncronizes item colors with current color settings if required, NOTE: overwrites internal values! + virtual void syncSysColors(); + + ///set select mode, see also col_frame_sel + virtual void setSelected(bool selected){cc_item_selected = selected;}; + ///set enable mode, see also cc_item_enabled + virtual void setEnable(bool enabled){cc_item_enabled = enabled;}; + + ///get select mode, see also setSelected() above + virtual bool isSelected(){return cc_item_selected;}; + ///get enable mode, see also setEnable() above + virtual bool isEnabled(){return cc_item_enabled;}; + + ///get current index of item, see also attribut cc_item_index + virtual int getIndex(){return cc_item_index;}; + ///set an index to item, see also attribut cc_item_index. + ///To generate an index, use genIndex() + virtual void setIndex(const int& index){cc_item_index = index;}; + + ///sets page location of current item, parameter as uint8_t, see: cc_page_number + virtual void setPageNumber(const uint8_t& on_page_number){cc_page_number = on_page_number;}; + ///returns current number of page location of current item, see: cc_page_number + virtual u_int8_t getPageNumber(){return cc_page_number;}; + + ///set screen x-position, parameter as uint8_t, percent x value related to current width of parent form or screen + virtual void setXPosP(const uint8_t& xpos_percent); + ///set screen y-position, parameter as uint8_t, percent y value related to current height of parent form or screen + virtual void setYPosP(const uint8_t& ypos_percent); + ///set x and y position as percent value related to current parent form or screen dimensions at once + virtual void setPosP(const uint8_t& xpos_percent, const uint8_t& ypos_percent); + + ///do center item on screen or within a parent form, parameter along_mode assigns direction of centering + virtual void setCenterPos(int along_mode = CC_ALONG_X | CC_ALONG_Y); + + ///set item height, parameter as uint8_t, as percent value related to current height of parent form or screen + virtual void setHeightP(const uint8_t& h_percent); + ///set item width, parameter as uint8_t, as percent value related to current width of parent form or screen + virtual void setWidthP(const uint8_t& w_percent); +}; + +#endif diff --git a/src/gui/components/cc_item_infobox.cpp b/src/gui/components/cc_item_infobox.cpp index 676a1db3a..01a03fba3 100644 --- a/src/gui/components/cc_item_infobox.cpp +++ b/src/gui/components/cc_item_infobox.cpp @@ -43,7 +43,7 @@ CComponentsInfoBox::CComponentsInfoBox( const int& x_pos, const int mode, Font* font_text, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_text, fb_pixel_t color_frame, fb_pixel_t color_body, @@ -55,7 +55,7 @@ CComponentsInfoBox::CComponentsInfoBox( const int& x_pos, y = y_pos; width = w; height = h; - shadow = has_shadow; + shadow = shadow_mode; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; @@ -110,7 +110,7 @@ void CComponentsInfoBox::paintPicture() pic->setColorBody(col_body); //set gradient behavior of pic object - if (col_body_gradient) + if (cc_body_gradient_enable) pic->doPaintBg(false); //fit icon into frame @@ -150,7 +150,7 @@ void CComponentsInfoBox::paint(bool do_save_bg) cctext->doPaintTextBoxBg(ct_paint_textbg); cctext->doPaintBg(false); cctext->setTextColor(ct_col_text); - cctext->enableTboxSaveScreen(save_tbox_screen); + cctext->enableTboxSaveScreen(cc_txt_save_screen); //calculate vars for x-position and dimensions int tx = x_offset + x_text + pic_w; diff --git a/src/gui/components/cc_item_infobox.h b/src/gui/components/cc_item_infobox.h index 6a86a6dc6..189dbb42c 100644 --- a/src/gui/components/cc_item_infobox.h +++ b/src/gui/components/cc_item_infobox.h @@ -32,6 +32,7 @@ #include "cc_item_text.h" #include "cc_item_picture.h" +#include "cc_item.h" #include //! Sub class of CComponentsItem. Shows box with text and optional icon on screen. @@ -69,7 +70,7 @@ class CComponentsInfoBox : public CComponentsText const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_text = COL_MENUCONTENT_TEXT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, @@ -78,13 +79,11 @@ class CComponentsInfoBox : public CComponentsText ~CComponentsInfoBox(); ///set property: space around fram and beetween picture and textbox - inline void setSpaceOffset(const int offset){x_offset = offset;}; + void setSpaceOffset(const int offset){x_offset = offset;}; ///set property: path or name of displayed image, parameter as string void setPicture(const std::string& picture_name); ///set property: path or name of displayed image, parameter as const char* void setPicture(const char* picture_name); - ///set property: gradient behavior - void enableGradient(bool enable) { col_body_gradient = enable; } ///paint item void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); }; diff --git a/src/gui/components/cc_item_picture.cpp b/src/gui/components/cc_item_picture.cpp index 3dc5a60eb..78ad584df 100644 --- a/src/gui/components/cc_item_picture.cpp +++ b/src/gui/components/cc_item_picture.cpp @@ -44,26 +44,26 @@ using namespace std; CComponentsPicture::CComponentsPicture( const int &x_pos, const int &y_pos, const int &w, const int &h, const std::string& image_name, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent) { - init(x_pos, y_pos, w, h, image_name, parent, has_shadow, color_frame, color_background, color_shadow, transparent, SCALE); + init(x_pos, y_pos, w, h, image_name, parent, shadow_mode, color_frame, color_background, color_shadow, transparent, SCALE); } CComponentsPicture::CComponentsPicture( const int &x_pos, const int &y_pos, const std::string& image_name, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent) { - init(x_pos, y_pos, 0, 0, image_name, parent, has_shadow, color_frame, color_background, color_shadow, transparent, NO_SCALE); + init(x_pos, y_pos, 0, 0, image_name, parent, shadow_mode, color_frame, color_background, color_shadow, transparent, NO_SCALE); } void CComponentsPicture::init( const int &x_pos, const int &y_pos, const int &w, const int &h, const string& image_name, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent, bool allow_scale) { @@ -75,17 +75,19 @@ void CComponentsPicture::init( const int &x_pos, const int &y_pos, const int &w, y = y_pos; width = dx = w; height = dy = h; - pic_name = image_name; - shadow = has_shadow; + pic_name = pic_name_old = image_name; + shadow = shadow_mode; shadow_w = SHADOW_OFFSET; col_frame = color_frame; col_body = color_background; col_shadow = color_shadow; do_scale = allow_scale; - + image_cache = NULL; //image + enable_cache = false; is_image_painted= false; do_paint = true; image_transparent = transparent; + cc_paint_cache = false; //bg keep_dx_aspect = false; keep_dy_aspect = false; @@ -93,8 +95,19 @@ void CComponentsPicture::init( const int &x_pos, const int &y_pos, const int &w, initParent(parent); } +void CComponentsPicture::clearCache() +{ + if (image_cache){ + delete[] image_cache; + image_cache = NULL; + } +} + void CComponentsPicture::setPicture(const std::string& picture_name) { + if (pic_name == picture_name) + return; + clearCache(); pic_name = picture_name; initCCItem(); } @@ -157,6 +170,9 @@ void CComponentsPicture::initCCItem() if (width == dx && height == dy) return; + //clean up possible cache on changed dimensions + clearCache(); + //temporarily vars int w_2scale = width; int h_2scale = height; @@ -210,11 +226,17 @@ int CComponentsPicture::getHeight() void CComponentsPicture::paintPicture() { + struct timeval t1, t2; + if (debug) + gettimeofday(&t1, NULL); + is_image_painted = false; //initialize image position int x_pic = x; int y_pic = y; initPosition(&x_pic, &y_pic); + x_pic += fr_thickness; + y_pic += fr_thickness; initCCItem(); if (pic_name.empty()) @@ -222,12 +244,26 @@ void CComponentsPicture::paintPicture() if (cc_allow_paint){ dprintf(DEBUG_INFO, "[CComponentsPicture] %s: paint image file: pic_name=%s\n", __func__, pic_name.c_str()); - frameBuffer->SetTransparent(image_transparent); - if (do_scale) - is_image_painted = g_PicViewer->DisplayImage(pic_name, x_pic, y_pic, width, height); - else - is_image_painted = frameBuffer->paintIcon(pic_name, x_pic, y_pic, height, 1, do_paint, paint_bg, col_body); - frameBuffer->SetTransparentDefault(); + if (image_cache == NULL){ + frameBuffer->SetTransparent(image_transparent); + if (do_scale) + is_image_painted = g_PicViewer->DisplayImage(pic_name, x_pic, y_pic, width-2*fr_thickness, height-2*fr_thickness); + else + is_image_painted = frameBuffer->paintIcon(pic_name, x_pic, y_pic, height, 1, do_paint, paint_bg, col_body); + frameBuffer->SetTransparentDefault(); + if (enable_cache) + image_cache = getScreen(x_pic, y_pic, width, height); + }else{ + frameBuffer->RestoreScreen(x_pic, y_pic, width, height, image_cache); + } + } + + //benchmark + if (debug){ + gettimeofday(&t2, NULL); + uint64_t duration = ((t2.tv_sec * 1000000ULL + t2.tv_usec) - (t1.tv_sec * 1000000ULL + t1.tv_usec)) / 1000ULL; + if (duration) + fprintf(stderr, "\033[33m[CComponentsPicture] %s: %llu ms to paint image \033[0m\n", __func__, duration); } } @@ -239,21 +275,34 @@ void CComponentsPicture::paint(bool do_save_bg) paintPicture(); } -void CComponentsPicture::hide(bool no_restore) +void CComponentsPicture::hide() { - hideCCItem(no_restore); + CComponents::hide(); is_image_painted = false; } +bool CComponentsPicture::hasChanges() +{ + bool ret = false; + if (pic_name != pic_name_old){ + pic_name_old = pic_name; + ret = true; + } + if (CCDraw::hasChanges()) + ret = true; + + return ret; +} + CComponentsChannelLogo::CComponentsChannelLogo( const int &x_pos, const int &y_pos, const int &w, const int &h, const std::string& channelName, const uint64_t& channelId, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent) :CComponentsPicture(x_pos, y_pos, w, h, - "", parent, has_shadow, + "", parent, shadow_mode, color_frame, color_background, color_shadow, transparent) { init(channelId, channelName, SCALE); @@ -263,10 +312,10 @@ CComponentsChannelLogo::CComponentsChannelLogo( const int &x_pos, const int &y_p const std::string& channelName, const uint64_t& channelId, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent) :CComponentsPicture(x_pos, y_pos, 0, 0, - "", parent, has_shadow, + "", parent, shadow_mode, color_frame, color_background, color_shadow, transparent) { init(channelId, channelName, NO_SCALE); diff --git a/src/gui/components/cc_item_picture.h b/src/gui/components/cc_item_picture.h index 4915e5e3f..2ca4639b3 100644 --- a/src/gui/components/cc_item_picture.h +++ b/src/gui/components/cc_item_picture.h @@ -32,6 +32,7 @@ #endif #include "cc_base.h" +#include "cc_item.h" #include #include @@ -49,11 +50,16 @@ class CComponentsPicture : public CComponentsItem ///possible image formats std::vector v_ext; + ///option to enable disable cache, default = false + bool enable_cache; + ///screen cache content for painted image + fb_pixel_t *image_cache; + ///current original image dimensions int dx, dy; ///property: name of image (without extensionn) full path to image (with extension), icon names to find in /widget/icons.h, icons will paint never scaled - std::string pic_name; + std::string pic_name, pic_name_old; ///indicate that image was sucessful painted bool is_image_painted; @@ -73,7 +79,7 @@ class CComponentsPicture : public CComponentsItem void init( const int &x_pos, const int &y_pos, const int &w, const int &h, const std::string& image_name, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, @@ -104,7 +110,7 @@ class CComponentsPicture : public CComponentsItem CComponentsPicture( const int &x_pos, const int &y_pos, const int &w, const int &h, const std::string& image_name, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_background = 0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, @@ -120,11 +126,15 @@ class CComponentsPicture : public CComponentsItem CComponentsPicture( const int &x_pos, const int &y_pos, const std::string& image_name, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_background = 0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, int transparent = CFrameBuffer::TM_NONE); + virtual~CComponentsPicture() + { + delete[]image_cache; + } ///sets an image name (unscaled icons only), full image path or url to an image file virtual void setPicture(const std::string& picture_name); @@ -152,8 +162,17 @@ class CComponentsPicture : public CComponentsItem ///paint item virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); - ///hide item - virtual void hide(bool no_restore = false); + ///hide item, see also CComponents::hide(); + virtual void hide(); + + virtual bool hasChanges(); + + ///remove possible cache + virtual void clearCache(); + ///enable/disable image cache + virtual void enableCache(bool enable = true){if (enable_cache == enable) return; enable_cache = enable; if (!enable_cache) clearCache();} + ///disable image cache, makes clean up too + virtual void disableCache(){enableCache(false);} }; class CComponentsPictureScalable : public CComponentsPicture @@ -166,12 +185,12 @@ class CComponentsPictureScalable : public CComponentsPicture CComponentsPictureScalable( const int &x_pos, const int &y_pos, const std::string& image_name, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_background = 0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, int transparent = CFrameBuffer::TM_NONE) - : CComponentsPicture(x_pos, y_pos, 0, 0, image_name, parent, has_shadow, color_frame, color_background, color_shadow, transparent){}; + : CComponentsPicture(x_pos, y_pos, 0, 0, image_name, parent, shadow_mode, color_frame, color_background, color_shadow, transparent){}; }; class CComponentsChannelLogo : public CComponentsPicture @@ -201,7 +220,7 @@ class CComponentsChannelLogo : public CComponentsPicture const std::string& channelName = "", const uint64_t& channelId =0, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_background = 0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, @@ -217,7 +236,7 @@ class CComponentsChannelLogo : public CComponentsPicture const std::string& channelName = "", const uint64_t& channelId =0, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_background = 0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, @@ -249,12 +268,12 @@ class CComponentsChannelLogoScalable : public CComponentsChannelLogo const std::string& channelName = "", const uint64_t& channelId =0, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_background = 0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, int transparent = CFrameBuffer::TM_BLACK) - : CComponentsChannelLogo(x_pos, y_pos, 0, 0, channelName, channelId, parent, has_shadow, color_frame, color_background, color_shadow, transparent){}; + : CComponentsChannelLogo(x_pos, y_pos, 0, 0, channelName, channelId, parent, shadow_mode, color_frame, color_background, color_shadow, transparent){}; }; #endif diff --git a/src/gui/components/cc_item_progressbar.cpp b/src/gui/components/cc_item_progressbar.cpp index 0ddb9ef2e..e0e1afbf6 100644 --- a/src/gui/components/cc_item_progressbar.cpp +++ b/src/gui/components/cc_item_progressbar.cpp @@ -30,7 +30,7 @@ #include #include #include - +#include #include "cc_item_progressbar.h" #define ITEMW 4 #define POINT 2 @@ -39,10 +39,18 @@ #define GREEN 0x00FF00 #define YELLOW 0xFFFF00 -CProgressBar::CProgressBar( const int x_pos, const int y_pos, const int w, const int h, - fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow, - const fb_pixel_t active_col, const fb_pixel_t passive_col, - const int r, const int g, const int b, +CProgressBar::CProgressBar( const int x_pos, + const int y_pos, + const int w, + const int h, + fb_pixel_t color_frame, + fb_pixel_t color_body, + fb_pixel_t color_shadow, + const fb_pixel_t active_col, + const fb_pixel_t passive_col, + const int R, + const int G, + const int Y, CComponentsForm *parent) { //CComponentsItem @@ -58,9 +66,9 @@ CProgressBar::CProgressBar( const int x_pos, const int y_pos, const int w, const col_body = color_body; col_shadow = color_shadow; - pb_red = r; - pb_green = g; - pb_yellow = b; + pb_red = R; + pb_green = G; + pb_yellow = Y; pb_active_col = active_col; pb_passive_col = passive_col; @@ -80,6 +88,7 @@ CProgressBar::CProgressBar( const int x_pos, const int y_pos, const int w, const pb_height = 0; pb_start_x_passive = 0; pb_passive_width = width; + cc_paint_cache = false; initParent(parent); } @@ -124,94 +133,122 @@ class CProgressBarCache { private: // keys to lookup: - int pb_height, pb_width; - int pb_active_col, pb_passive_col; - int design; - bool pb_invert, gradient; - int pb_red, pb_yellow, pb_green; - + int pbc_height, pbc_width; + int pbc_active_col, pbc_passive_col; + int pbc_design; + bool pbc_invert, pbc_gradient; + int pbc_red, pbc_green, pbc_yellow; int yoff; - fb_pixel_t *active, *passive; + fb_pixel_t *pbc_active, *pbc_passive; + ; static inline unsigned int make16color(__u32 rgb){return 0xFF000000 | rgb;}; - void paintBoxRel(fb_pixel_t *b, int x, int y, int dx, int dy, fb_pixel_t col); - void applyGradient(fb_pixel_t *buf); - void createBitmaps(); - CProgressBarCache(int _height, int _width, int _pb_active_col, int _pb_passive_col, int _design, bool _invert, bool _gradient, int _red, int _yellow, int _green) - : pb_height(_height), pb_width(_width), pb_active_col(_pb_active_col), pb_passive_col(_pb_passive_col), design(_design), pb_invert(_invert), gradient(_gradient), - pb_red(_red), pb_yellow(_yellow), pb_green(_green), yoff(0) + void pbcPaintBoxRel(int x, int y, int dx, int dy, fb_pixel_t *pixbuf, fb_pixel_t col); + void pbcApplyGradient(fb_pixel_t *pixbuf); + void pbcCreateBitmaps(); + + CProgressBarCache( int dy, + int dx, + int active_col, + int passive_col, + int design, + bool enable_invert, + bool enable_gradient, + int R, + int G, + int Y) + : pbc_height(dy), + pbc_width(dx), + pbc_active_col(active_col), + pbc_passive_col(passive_col), + pbc_design(design), + pbc_invert(enable_invert), + pbc_gradient(enable_gradient), + pbc_red(R), + pbc_green(G), + pbc_yellow(Y), + yoff(0) { if (pbCache.size() > 10) - clear(); - createBitmaps(); + pbcClear(); + pbcCreateBitmaps(); } - void clear(); + void pbcClear(); public: - void paint(int x, int y, int pb_active_width, int pb_passive_width); - static CProgressBarCache *lookup(int _height, int _width, int _pb_active_col, int _pb_passive_col, int _design, bool _invert, bool _gradient, int _red, int _yellow, int _green); + void pbcPaint(int x, int y, int pbc_active_width, int pbc_passive_width); + static CProgressBarCache *pbcLookup( int dy, + int dx, + int active_col, + int passive_col, + int design, + bool enable_invert, + bool enable_gradient, + int R, + int G, + int Y); }; -void CProgressBarCache::clear() +void CProgressBarCache::pbcClear() { for (std::vector::iterator it = pbCache.begin(); it != pbCache.end(); ++it) { - if ((*it)->active) - free((*it)->active); - if ((*it)->passive) - free((*it)->passive); + if ((*it)->pbc_active) + free((*it)->pbc_active); + if ((*it)->pbc_passive) + free((*it)->pbc_passive); } pbCache.clear(); } -CProgressBarCache *CProgressBarCache::lookup(int _height, int _width, int _pb_active_col, int _pb_passive_col, int _design, bool _invert, bool _gradient, int _red, int _yellow, int _green) +CProgressBarCache *CProgressBarCache::pbcLookup(int dy, int dx, int active_col, int passive_col, int design, bool enable_invert, bool enable_gradient, int R, int G, int Y) { // sanitize - if (_design == CProgressBar::PB_MONO) - _red = _yellow = _green = 0; + if (design == CProgressBar::PB_MONO) + R = G = Y = 0; // lookup std::vector::iterator it = pbCache.begin(); - for (; it != pbCache.end() && ((*it)->pb_height != _height || (*it)->pb_width != _width || - (*it)->pb_active_col != _pb_active_col || (*it)->pb_passive_col != _pb_passive_col || - (*it)->design != _design || (*it)->pb_invert != _invert || (*it)->gradient != _gradient || - (*it)->pb_red != _red || (*it)->pb_yellow != _yellow || (*it)->pb_green != _green); ++it); + for (; it != pbCache.end() && ((*it)->pbc_height != dy || (*it)->pbc_width != dx || + (*it)->pbc_active_col != active_col || (*it)->pbc_passive_col != passive_col || + (*it)->pbc_design != design || (*it)->pbc_invert != enable_invert || (*it)->pbc_gradient != enable_gradient || + (*it)->pbc_red != R || (*it)->pbc_yellow != Y || (*it)->pbc_green != G); ++it); if (it != pbCache.end()) return *it; - CProgressBarCache *pbc = new CProgressBarCache(_height, _width, _pb_active_col, _pb_passive_col, _design, _invert, _gradient, _red, _yellow, _green); + CProgressBarCache *pbc = new CProgressBarCache(dy, dx, active_col, passive_col, design, enable_invert, enable_gradient, R, G, Y); pbCache.push_back(pbc); return pbc; } -void CProgressBarCache::paint(int x, int y, int pb_active_width, int pb_passive_width) +void CProgressBarCache::pbcPaint(int x, int y, int pbc_active_width, int pbc_passive_width) { y += yoff; static CFrameBuffer *frameBuffer = CFrameBuffer::getInstance(); unsigned int stride = frameBuffer->getStride() / sizeof(fb_pixel_t); fb_pixel_t *p = frameBuffer->getFrameBufferPointer() + y * stride + x; - int off = stride - pb_width; - if (pb_active_width > pb_width) - pb_active_width = pb_width; - if (pb_active_width + pb_passive_width != pb_width) - pb_passive_width = pb_width - pb_active_width; - fb_pixel_t *ap = active; - fb_pixel_t *pp = passive; - for (int h = 0; h < pb_height; h++) { + int off = stride - pbc_width; + if (pbc_active_width > pbc_width) + pbc_active_width = pbc_width; + if (pbc_active_width + pbc_passive_width != pbc_width) + pbc_passive_width = pbc_width - pbc_active_width; + fb_pixel_t *ap = pbc_active; + fb_pixel_t *pp = pbc_passive; + for (int h = 0; h < pbc_height; h++) { int w = 0; - for (; w < pb_active_width; w++, p++, ap++) + for (; w < pbc_active_width; w++, p++, ap++) if (*ap) *p = *ap; - pp += pb_active_width; - for (; w < pb_width; w++, p++, pp++) + pp += pbc_active_width; + for (; w < pbc_width; w++, p++, pp++) if (*pp) *p = *pp; - ap += pb_passive_width; + ap += pbc_passive_width; p += off; } } -void CProgressBarCache::paintBoxRel(fb_pixel_t *b, int x, int y, int dx, int dy, fb_pixel_t col) +void CProgressBarCache::pbcPaintBoxRel(int x, int y, int dx, int dy, fb_pixel_t *pixbuf, fb_pixel_t col) { if (x < 0) { dx -= x; @@ -221,80 +258,80 @@ void CProgressBarCache::paintBoxRel(fb_pixel_t *b, int x, int y, int dx, int dy, dy -= y; y = 0; } - if (x + dx > pb_width) - dx = pb_width - x; - if (y + dy > pb_height) - dy = pb_height - y; + if (x + dx > pbc_width) + dx = pbc_width - x; + if (y + dy > pbc_height) + dy = pbc_height - y; if (dx < 1 || dy < 1) return; - b += pb_width * y + x; - fb_pixel_t *e = b + pb_width * (dy - 1) + dx; - int off = pb_width - dx; - while (b < e) { - fb_pixel_t *ex = b + dx; - while (b < ex) - *b++ = col; - b += off; + pixbuf += pbc_width * y + x; + fb_pixel_t *e = pixbuf + pbc_width * (dy - 1) + dx; + int off = pbc_width - dx; + while (pixbuf < e) { + fb_pixel_t *ex = pixbuf + dx; + while (pixbuf < ex) + *pixbuf++ = col; + pixbuf += off; } } -void CProgressBarCache::createBitmaps() +void CProgressBarCache::pbcCreateBitmaps() { - active = (fb_pixel_t *) calloc(1, pb_width * pb_height * sizeof(fb_pixel_t)); - if (!active) + pbc_active = (fb_pixel_t *) calloc(1, pbc_width * pbc_height * sizeof(fb_pixel_t)); + if (!pbc_active) return; - passive = (fb_pixel_t *) calloc(1, pb_width * pb_height * sizeof(fb_pixel_t)); - if (!passive) { - free(active); + pbc_passive = (fb_pixel_t *) calloc(1, pbc_width * pbc_height * sizeof(fb_pixel_t)); + if (!pbc_passive) { + free(pbc_active); return; } int itemw = ITEMW, itemh = ITEMW, pointx = POINT, pointy = POINT; - switch (design){ + switch (pbc_design){ default: case CProgressBar::PB_MONO: // monochrome - paintBoxRel(active, 0, 0, pb_width, pb_height, pb_active_col ); - paintBoxRel(passive, 0, 0, pb_width, pb_height, pb_passive_col); - if (gradient) { - applyGradient(active); - applyGradient(passive); + pbcPaintBoxRel(0, 0, pbc_width, pbc_height, pbc_active, pbc_active_col); + pbcPaintBoxRel(0, 0, pbc_width, pbc_height, pbc_passive, pbc_passive_col); + if (pbc_gradient) { + pbcApplyGradient(pbc_active); + pbcApplyGradient(pbc_passive); } return; case CProgressBar::PB_MATRIX: // ::::: matrix break; case CProgressBar::PB_LINES_V: // ||||| vert. lines - itemh = pb_height; - pointy = pb_height; + itemh = pbc_height; + pointy = pbc_height; break; case CProgressBar::PB_LINES_H: // ===== horiz. lines itemw = POINT; break; case CProgressBar::PB_COLOR: // filled color itemw = 1; - itemh = pb_height; - pointy = pb_height; + itemh = pbc_height; + pointy = pbc_height; break; } const int spc = itemh - pointy; /* space between horizontal lines / points */ - int hcnt = (pb_height + spc) / itemh; /* how many POINTs is the bar high */ - yoff = (pb_height + spc - itemh * hcnt) / 2; + int hcnt = (pbc_height + spc) / itemh; /* how many POINTs is the bar high */ + yoff = (pbc_height + spc - itemh * hcnt) / 2; int i = 0; int sh_x = 0; /* red, yellow, green are given in percent */ - int rd = pb_red * pb_width / (100 * itemw); /* how many POINTs red */ - int yw = pb_yellow * pb_width / (100 * itemw); /* how many POINTs yellow */ - int gn = pb_green * pb_width / (100 * itemw); /* how many POINTs green */ + int rd = pbc_red * pbc_width / (100 * itemw); /* how many POINTs red */ + int yw = pbc_yellow * pbc_width / (100 * itemw); /* how many POINTs yellow */ + int gn = pbc_green * pbc_width / (100 * itemw); /* how many POINTs green */ // fixup rounding errors - while ((rd + yw + gn) * itemw < pb_width) { + while ((rd + yw + gn) * itemw < pbc_width) { if (gn) gn++; - if (yw && ((rd + yw + gn) * itemw < pb_width)) + if (yw && ((rd + yw + gn) * itemw < pbc_width)) yw++; - if (rd && ((rd + yw + gn) * itemw < pb_width)) + if (rd && ((rd + yw + gn) * itemw < pbc_width)) rd++; } @@ -310,7 +347,7 @@ void CProgressBarCache::createBitmaps() fb_pixel_t color = make16color(rgb); int sh_y = 0; for (int j = 0; j < hcnt; j++, sh_y += itemh) - paintBoxRel(active, sh_x, sh_y, pointx, pointy, color); + pbcPaintBoxRel(sh_x, sh_y, pointx, pointy, pbc_active, color); } step = yw - rd - 1; if (step < 1) @@ -321,7 +358,7 @@ void CProgressBarCache::createBitmaps() fb_pixel_t color = make16color(rgb); int sh_y = 0; for (int j = 0; j < hcnt; j++, sh_y += itemh) - paintBoxRel(active, sh_x, sh_y, pointx, pointy, color); + pbcPaintBoxRel(sh_x, sh_y, pointx, pointy, pbc_active, color); } int off = diff; b = 0; @@ -334,12 +371,12 @@ void CProgressBarCache::createBitmaps() fb_pixel_t color = make16color(rgb); int sh_y = 0; for (int j = 0; j < hcnt; j++, sh_y += itemh) - paintBoxRel(active, sh_x, sh_y, pointx, pointy, color); + pbcPaintBoxRel(sh_x, sh_y, pointx, pointy, pbc_active, color); } - if (pb_invert) { - for (int l = 0; l < pb_height; l++) { - fb_pixel_t *as = active + l * pb_width; - fb_pixel_t *ae = as + pb_width - 1; + if (pbc_invert) { + for (int l = 0; l < pbc_height; l++) { + fb_pixel_t *as = pbc_active + l * pbc_width; + fb_pixel_t *ae = as + pbc_width - 1; for (; as < ae; as++, ae--) { fb_pixel_t t = *as; *as = *ae; @@ -348,11 +385,11 @@ void CProgressBarCache::createBitmaps() } } - if (gradient) - applyGradient(active); + if (pbc_gradient) + pbcApplyGradient(pbc_active); - fb_pixel_t *a = active, *p = passive; - fb_pixel_t *end = a + pb_width * pb_height; + fb_pixel_t *a = pbc_active, *p = pbc_passive; + fb_pixel_t *end = a + pbc_width * pbc_height; for (; a < end; a++, p++) { fb_pixel_t q = *a; unsigned int gray = ((q & 0xff) + ((q >> 8) & 0xff) + ((q >> 16) & 0xff)) / 3; @@ -367,17 +404,17 @@ void CProgressBarCache::createBitmaps() } } -void CProgressBarCache::applyGradient(fb_pixel_t *b) +void CProgressBarCache::pbcApplyGradient(fb_pixel_t *b) { - for (int y = 0; y < pb_height; y++) { - int _o = y * pb_width; + for (int y = 0; y < pbc_height; y++) { + int _o = y * pbc_width; fb_pixel_t last_old = 0; fb_pixel_t last_new = 0; - for (int _x = pb_width - 1; _x > -1; _x--) { + for (int _x = pbc_width - 1; _x > -1; _x--) { fb_pixel_t &v = *(b + _o + _x); if (v != last_old) { last_old = v; - double s = sin((y + .5) * M_PI / pb_height) * .8 + .2; + double s = sin((y + .5) * M_PI / pbc_height) * .8 + .2; float fr = float(((last_old >> 16) & 0xff) * s + 0.5); float fg = float(((last_old >> 8) & 0xff) * s + 0.5); float fb = float(((last_old ) & 0xff) * s + 0.5); @@ -393,6 +430,10 @@ void CProgressBarCache::applyGradient(fb_pixel_t *b) void CProgressBar::paintProgress(bool do_save_bg) { + struct timeval t1, t2; + if (debug) + gettimeofday(&t1, NULL); + if (*pb_design == PB_OFF) { paintInit(false); return; @@ -424,15 +465,23 @@ void CProgressBar::paintProgress(bool do_save_bg) if (cc_allow_paint){ if (pb_active_width != pb_last_width) { - CProgressBarCache *pbc = CProgressBarCache::lookup(pb_height, pb_max_width, pb_active_col, pb_passive_col, *pb_design, pb_invert, *pb_gradient, pb_red, pb_yellow, pb_green); + CProgressBarCache *pbc = CProgressBarCache::pbcLookup(pb_height, pb_max_width, pb_active_col, pb_passive_col, *pb_design, pb_invert, *pb_gradient, pb_red, pb_yellow, pb_green); if (pbc) - pbc->paint(pb_x, pb_y, pb_active_width, pb_passive_width); + pbc->pbcPaint(pb_x, pb_y, pb_active_width, pb_passive_width); is_painted = true; } } if (is_painted) pb_last_width = pb_active_width; + + //benchmark + if (debug){ + gettimeofday(&t2, NULL); + uint64_t duration = ((t2.tv_sec * 1000000ULL + t2.tv_usec) - (t1.tv_sec * 1000000ULL + t1.tv_usec)) / 1000ULL; + if (duration) + fprintf(stderr, "\033[33m[CProgressBar] %s: %llu ms to paint progress \033[0m\n",__func__, duration); + } } diff --git a/src/gui/components/cc_item_progressbar.h b/src/gui/components/cc_item_progressbar.h index 4901f1260..c3bcb40b5 100644 --- a/src/gui/components/cc_item_progressbar.h +++ b/src/gui/components/cc_item_progressbar.h @@ -50,7 +50,7 @@ #include "config.h" #include "cc_base.h" - +#include "cc_item.h" #include class CProgressBar : public CComponentsItem @@ -91,14 +91,21 @@ class CProgressBar : public CComponentsItem ///parameters: ///x_pos, y_pos, w, h: position and dimension in pixel ///w, h: width / height of bar. Can later be set with paintProgressbar. - ///r, g, b: percentage of the bar where red/green/yellow is used, only used for colored designs + ///R, G, Y: percentage of the bar where red/green/yellow is used, only used for colored designs ///active_col, passive_col: sets colors for displayed values, activ_col means the the displayed progress ///color_frame, color_body, color_shadow: colores of progressbar for frame, body and shadow, Note: color of frame is ineffective on fr_thickness = 0 - CProgressBar( const int x_pos = 0, const int y_pos = 0, - const int w = -1, const int h = -1, - fb_pixel_t color_frame = 0, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, - const fb_pixel_t active_col = COL_INFOBAR_PLUS_7, const fb_pixel_t passive_col = COL_INFOBAR_PLUS_3, - const int r = 40, const int g = 100, const int b =70, + CProgressBar( const int x_pos = 0, + const int y_pos = 0, + const int w = -1, + const int h = -1, + fb_pixel_t color_frame = 0, + fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, + fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0, + const fb_pixel_t active_col = COL_INFOBAR_PLUS_7, + const fb_pixel_t passive_col = COL_INFOBAR_PLUS_3, + const int R = 40, + const int G = 100, + const int Y = 70, CComponentsForm *parent = NULL); diff --git a/src/gui/components/cc_item_shapes.cpp b/src/gui/components/cc_item_shapes.cpp index c4acb6514..d6c623b29 100644 --- a/src/gui/components/cc_item_shapes.cpp +++ b/src/gui/components/cc_item_shapes.cpp @@ -37,17 +37,17 @@ using namespace std; //sub class CComponentsShapeSquare from CComponentsItem CComponentsShapeSquare::CComponentsShapeSquare( const int x_pos, const int y_pos, const int w, const int h, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { //CComponentsItem cc_item_type = CC_ITEMTYPE_SHAPE_SQUARE; - x = x_pos; - y = y_pos; - width = w; - height = h; - shadow = has_shadow; + x = x_old = x_pos; + y = y_old = y_pos; + width = width_old = w; + height = height_old = h; + shadow = shadow_mode; shadow_w = SHADOW_OFFSET; col_frame = color_frame; col_body = color_body; @@ -65,7 +65,7 @@ void CComponentsShapeSquare::paint(bool do_save_bg) //sub class CComponentsShapeCircle from CComponentsItem CComponentsShapeCircle::CComponentsShapeCircle( int x_pos, int y_pos, int diam, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { //CComponents, CComponentsItem @@ -75,7 +75,7 @@ CComponentsShapeCircle::CComponentsShapeCircle( int x_pos, int y_pos, int diam, x = x_pos; y = y_pos; //width = height = d = diam; - shadow = has_shadow; + shadow = shadow_mode; shadow_w = SHADOW_OFFSET; col_frame = color_frame; col_body = color_body; diff --git a/src/gui/components/cc_item_shapes.h b/src/gui/components/cc_item_shapes.h index 7457d88e3..47e3ecf14 100644 --- a/src/gui/components/cc_item_shapes.h +++ b/src/gui/components/cc_item_shapes.h @@ -31,6 +31,7 @@ #endif #include "cc_base.h" +#include "cc_item.h" //! Sub class of CComponentsItem. Shows a shape with given dimensions and color on screen. /*! @@ -45,7 +46,7 @@ class CComponentsShapeCircle : public CComponentsItem public: CComponentsShapeCircle( const int x_pos, const int y_pos, const int diam, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); ///set property: diam @@ -62,7 +63,7 @@ class CComponentsShapeSquare : public CComponentsItem public: CComponentsShapeSquare( const int x_pos, const int y_pos, const int w, const int h, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); diff --git a/src/gui/components/cc_item_text.cpp b/src/gui/components/cc_item_text.cpp index dd6bec049..bfe7a622a 100644 --- a/src/gui/components/cc_item_text.cpp +++ b/src/gui/components/cc_item_text.cpp @@ -43,21 +43,23 @@ CComponentsText::CComponentsText( CComponentsForm *parent, std::string text, const int mode, Font* font_text, - bool has_shadow, + const int& font_style, + int shadow_mode, fb_pixel_t color_text, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { - initVarText(x_pos, y_pos, w, h, text, mode, font_text, parent, has_shadow, color_text, color_frame, color_body, color_shadow); + initVarText(x_pos, y_pos, w, h, text, mode, font_text, font_style, parent, shadow_mode, color_text, color_frame, color_body, color_shadow); } CComponentsText::CComponentsText( const int x_pos, const int y_pos, const int w, const int h, std::string text, const int mode, Font* font_text, + const int& font_style, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_text, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { - initVarText(x_pos, y_pos, w, h, text, mode, font_text, parent, has_shadow, color_text, color_frame, color_body, color_shadow); + initVarText(x_pos, y_pos, w, h, text, mode, font_text, font_style, parent, shadow_mode, color_text, color_frame, color_body, color_shadow); } CComponentsText::~CComponentsText() @@ -71,8 +73,9 @@ void CComponentsText::initVarText( const int x_pos, const int y_pos, const int w std::string text, const int mode, Font* font_text, + const int& font_style, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_text, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { cc_item_type = CC_ITEMBOX_TEXT; @@ -81,10 +84,10 @@ void CComponentsText::initVarText( const int x_pos, const int y_pos, const int w ct_text = text; ct_old_text = ct_text; ct_text_mode = mode; - ct_text_style = FONT_STYLE_REGULAR; + ct_text_style = font_style; - iX = x = x_pos; - iY = y = y_pos; + iX = x = x_old = x_pos; //TODO: equalize inhertited member names + iY = y = y_old = y_pos; iWidth=width = w; iHeight=height = h; @@ -94,13 +97,13 @@ void CComponentsText::initVarText( const int x_pos, const int y_pos, const int w ct_text_Hborder = 1; ct_text_Vborder = 0; - shadow = has_shadow; + shadow = shadow_mode; ct_col_text = color_text; - ct_old_col_text = 0; + ct_old_col_text = ct_col_text; col_frame = color_frame; col_body = color_body; col_shadow = color_shadow; - + fr_thickness = 0; ct_text_sent = false; ct_paint_textbg = false; ct_force_text_paint = false; @@ -148,18 +151,19 @@ void CComponentsText::initCCText() ct_textbox->setTextColor(ct_col_text); ct_textbox->setWindowMaxDimensions(iWidth, iHeight); ct_textbox->setWindowMinDimensions(iWidth, iHeight); - ct_textbox->enableSaveScreen(save_tbox_screen); + ct_textbox->enableSaveScreen(cc_txt_save_screen); ct_textbox->enableUTF8(ct_utf8_encoded); //observe behavior of parent form if available bool force_text_paint = ct_force_text_paint; +#if 0 //FIXME., if (cc_parent){ //if any embedded text item was hided because of hided parent form, //we must ensure repaint of text, otherwise text item is not visible if (cc_parent->isPainted()) force_text_paint = true; } - +#endif //send text to CTextBox object, but force text paint text if force_text_paint option is enabled //this is managed by CTextBox object itself ct_text_sent = ct_textbox->setText(&ct_text, this->iWidth, force_text_paint); @@ -183,37 +187,44 @@ void CComponentsText::clearCCText() ct_textbox = NULL; } -void CComponentsText::setText(const std::string& stext, const int mode, Font* font_text, const fb_pixel_t& color_text, const int& style) +bool CComponentsText::setText(const std::string& stext, const int mode, Font* font_text, const fb_pixel_t& color_text, const int& style) { - ct_old_text = ct_text; - ct_text = stext; - if (mode != ~CTextBox::AUTO_WIDTH) - ct_text_mode = mode; - if (font_text) - ct_font = font_text; - if (color_text != 0) - setTextColor(color_text); - if (style != FONT_STYLE_REGULAR) - ct_text_style = style; + if (ct_text != stext || ct_text_mode != mode || ct_font != font_text || ct_col_text != color_text || ct_text_style != style ){ + if (ct_text != stext){ + ct_text = stext; + ct_old_text = ct_text; + } + if (ct_text_mode != mode /*|| mode != ~CTextBox::AUTO_WIDTH*/) + ct_text_mode = mode; + if (font_text) + ct_font = font_text; + if (color_text != 0) + setTextColor(color_text); + if (style != FONT_STYLE_REGULAR) + ct_text_style = style; - dprintf(DEBUG_DEBUG, "[CComponentsText] [%s - %d] ct_text: %s \n", __func__, __LINE__, ct_text.c_str()); + dprintf(DEBUG_DEBUG, "[CComponentsText] [%s - %d] ct_text: %s \n", __func__, __LINE__, ct_text.c_str()); + return true; + } + + return false; } -void CComponentsText::setText(neutrino_locale_t locale_text, int mode, Font* font_text, const fb_pixel_t& color_text, const int& style) +bool CComponentsText::setText(neutrino_locale_t locale_text, int mode, Font* font_text, const fb_pixel_t& color_text, const int& style) { string stext = g_Locale->getText(locale_text); - setText(stext, mode, font_text, color_text, style); + return setText(stext, mode, font_text, color_text, style); } -void CComponentsText::setText(const char* ctext, const int mode, Font* font_text, const fb_pixel_t& color_text, const int& style) +bool CComponentsText::setText(const char* ctext, const int mode, Font* font_text, const fb_pixel_t& color_text, const int& style) { - setText((string)ctext, mode, font_text, color_text, style); + return setText((string)ctext, mode, font_text, color_text, style); } -void CComponentsText::setText(const int digit, const int mode, Font* font_text, const fb_pixel_t& color_text, const int& style) +bool CComponentsText::setText(const int digit, const int mode, Font* font_text, const fb_pixel_t& color_text, const int& style) { string s_digit = iToString(digit); - setText(s_digit, mode, font_text, color_text, style); + return setText(s_digit, mode, font_text, color_text, style); } string CComponentsText::getTextFromFile(const string& path_to_textfile) @@ -244,15 +255,14 @@ bool CComponentsText::setTextFromFile(const string& path_to_textfile, const int if (txt.empty()) return false; - setText(txt, mode, font_text, color_text, style); - - return true; + return setText(txt, mode, font_text, color_text, style); } void CComponentsText::paintText(bool do_save_bg) { paintInit(do_save_bg); initCCText(); + if (ct_text_sent && cc_allow_paint) ct_textbox->paint(); ct_text_sent = false; @@ -263,12 +273,32 @@ void CComponentsText::paint(bool do_save_bg) paintText(do_save_bg); } -void CComponentsText::hide(bool no_restore) +void CComponentsText::hide() { if (ct_textbox) ct_textbox->hide(); ct_old_text = ""; - hideCCItem(no_restore); + CComponents::hide(); +} + +void CComponentsText::setXPos(const int& xpos) +{ + iX = x = xpos; +} + +void CComponentsText::setYPos(const int& ypos) +{ + iY = y = ypos; +} + +void CComponentsText::setHeight(const int& h) +{ + iHeight = height = h; +} + +void CComponentsText::setWidth(const int& w) +{ + iWidth = width = w; } //small helper to remove excessiv linbreaks @@ -308,7 +338,33 @@ int CComponentsText::getTextLinesAutoHeight(const int& textMaxHeight, const int& void CComponentsText::setTextColor(const fb_pixel_t& color_text) { - ct_col_text = color_text; - if (ct_textbox) - ct_textbox->setTextColor(ct_col_text); + if (ct_col_text != color_text){ + //ct_textbox->clearScreenBuffer(); + + ct_col_text = color_text; + if (ct_textbox) + ct_textbox->setTextColor(ct_col_text); + } } + +bool CComponentsText::clearSavedScreen() +{ + bool ret0 = CCDraw::clearSavedScreen(); + bool ret1 = false; +#if 0 + if (ct_textbox) + ret1 = ct_textbox->clearScreenBuffer(); +#endif + return max(ret0, ret1); +} +#if 0 +bool CComponentsText::enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color) +{ + if (CCDraw::enableColBodyGradient(enable_mode, sec_color)){ + if (ct_textbox) + ct_textbox->clearScreenBuffer(); + } + return false; +} +#endif + diff --git a/src/gui/components/cc_item_text.h b/src/gui/components/cc_item_text.h index c781be040..af36d128b 100644 --- a/src/gui/components/cc_item_text.h +++ b/src/gui/components/cc_item_text.h @@ -27,6 +27,8 @@ #define __CC_ITEM_TEXT_H__ #include "cc_base.h" +#include "cc_item.h" +#include "cc_text_screen.h" #include #include @@ -38,7 +40,7 @@ Handling of text parts based up CTextBox attributes and methodes. CComponentsText provides a interface to the embedded CTextBox object. */ -class CComponentsText : public CComponentsItem, public CBox +class CComponentsText : public CCTextScreen, public CComponentsItem, public CBox { protected: ///object: CTextBox object @@ -81,8 +83,9 @@ class CComponentsText : public CComponentsItem, public CBox std::string text, const int mode, Font* font_text, + const int& font_style, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_text, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow); ///destroy current CTextBox and CBox objects @@ -103,8 +106,9 @@ class CComponentsText : public CComponentsItem, public CBox std::string text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, + const int& font_style = CComponentsText::FONT_STYLE_REGULAR, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_text = COL_MENUCONTENT_TEXT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); CComponentsText( CComponentsForm *parent, @@ -112,14 +116,15 @@ class CComponentsText : public CComponentsItem, public CBox std::string text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, - bool has_shadow = CC_SHADOW_OFF, + const int& font_style = CComponentsText::FONT_STYLE_REGULAR, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_text = COL_MENUCONTENT_TEXT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); virtual ~CComponentsText(); ///default members to paint a text box and hide painted text ///hide textbox - void hide(bool no_restore = false); + void hide(); ///paint text box, parameter do_save_bg: default = true, causes fill of backckrond pixel buffer void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); @@ -137,26 +142,33 @@ class CComponentsText : public CComponentsItem, public CBox ///send option to CTextBox object to paint background box behind text or not virtual inline void doPaintTextBoxBg(bool do_paintbox_bg){ ct_paint_textbg = do_paintbox_bg;}; - ///set text as string also possible with overloades members for loacales, const char and text file - virtual void setText(const std::string& stext, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); - ///set text with const char* - virtual void setText(const char* ctext, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); - ///set text from locale - virtual void setText(neutrino_locale_t locale_text, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); - ///set text from digit, digit is integer - virtual void setText(const int digit, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); - ///set text directly from a textfile, path as string is required + ///set text as string also possible with overloades members for loacales, const char and text file, returns true if text was changed + virtual bool setText(const std::string& stext, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); + ///set text with const char*, returns true if text was changed + virtual bool setText(const char* ctext, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); + ///set text from locale, returns true if text was changed + virtual bool setText(neutrino_locale_t locale_text, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); + ///set text from digit, digit is integer, returns true if text was changed + virtual bool setText(const int digit, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); + ///set text directly from a textfile, path as string is required, returns true if text was changed virtual bool setTextFromFile(const std::string& path_to_textfile, const int mode = ~CTextBox::AUTO_WIDTH, Font* font_text = NULL, const fb_pixel_t& color_text = 0, const int& style = FONT_STYLE_REGULAR); ///get text directly from a textfile, path as string is required static std::string getTextFromFile(const std::string& path_to_textfile); ///returns current text content of text/label object as std::string virtual std::string getText(){return ct_text;}; + ///set screen x-position, parameter as int + virtual void setXPos(const int& xpos); + ///set screen y-position, parameter as int + virtual void setYPos(const int& ypos); + ///set height of component on screen + virtual void setHeight(const int& h); + ///set width of component on screen + virtual void setWidth(const int& w); + ///helper to remove linebreak chars from a string if needed virtual void removeLineBreaks(std::string& str); - ///returns true, if text was changed - virtual bool textChanged(){return ct_old_text != ct_text;}; ///force paint of text even if text was changed or not virtual void forceTextPaint(bool force_text_paint = true){ct_force_text_paint = force_text_paint;}; @@ -165,16 +177,46 @@ class CComponentsText : public CComponentsItem, public CBox ///returns count of lines from a text box page virtual int getTextLinesAutoHeight(const int& textMaxHeight, const int& textWidth, const int& mode); - // overload function from cc_base CComponents + ///allows to save bg screen behind text within CTextBox object, see also cc_txt_save_screen void enableTboxSaveScreen(bool mode) { - save_tbox_screen = mode; + if (cc_txt_save_screen == mode) + return; + cc_txt_save_screen = mode; if (ct_textbox) ct_textbox->enableSaveScreen(mode); } ///enable/disable utf8 encoding void enableUTF8(bool enable = true){ct_utf8_encoded = enable;} void disableUTF8(bool enable = false){enableUTF8(enable);} + /*!Clean up screen buffers from background layers. + * Paint cache and gradient cache not touched. + * The default basic methode CCDraw::clearSavedScreen() doesn't considering text bg screen, therefore + * we ensure also clean up the background of textbox object. + * Returns true if any buffer was cleane + */ + virtual bool clearSavedScreen(); +// ///set color gradient on/off, returns true if gradient mode was changed +// virtual bool enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color = 255 /*=COL_BACKGROUND*/); +}; + + +//! Sub class of CComponentsText. Shows text with transparent background +class CComponentsTextTransp : public CComponentsText +{ + public: + CComponentsTextTransp( CComponentsForm *parent, + const int x_pos = 10, const int y_pos = 10, const int w = 150, const int h = 50, + std::string text = "", + const int mode = CTextBox::AUTO_WIDTH, + Font* font_text = NULL, + const int& font_style = CComponentsText::FONT_STYLE_REGULAR, + fb_pixel_t color_text = COL_MENUCONTENT_TEXT) + :CComponentsText(x_pos, y_pos, w, h, text, mode, font_text, font_style, parent, CC_SHADOW_OFF, color_text) + { + doPaintBg(false); + enableTboxSaveScreen(true); + }; }; @@ -193,13 +235,14 @@ class CComponentsLabel : public CComponentsText std::string text = "", const int mode = CTextBox::AUTO_WIDTH, Font* font_text = NULL, + const int& font_style = CComponentsText::FONT_STYLE_REGULAR, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_text = COL_MENUCONTENTINACTIVE_TEXT, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0) - :CComponentsText(x_pos, y_pos, w, h, text, mode, font_text, parent, has_shadow, color_text, color_frame, color_body, color_shadow) + :CComponentsText(x_pos, y_pos, w, h, text, mode, font_text, font_style, parent, shadow_mode, color_text, color_frame, color_body, color_shadow) { cc_item_type = CC_ITEMTYPE_LABEL; }; diff --git a/src/gui/components/cc_item_tvpic.cpp b/src/gui/components/cc_item_tvpic.cpp index 24cdcf989..4d038d897 100644 --- a/src/gui/components/cc_item_tvpic.cpp +++ b/src/gui/components/cc_item_tvpic.cpp @@ -42,7 +42,7 @@ using namespace std; //sub class CComponentsPIP from CComponentsItem CComponentsPIP::CComponentsPIP( const int x_pos, const int y_pos, const int percent, CComponentsForm *parent, - bool has_shadow, + int shadow_mode, fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow) { //CComponents, CComponentsItem @@ -59,7 +59,7 @@ CComponentsPIP::CComponentsPIP( const int x_pos, const int y_pos, const int perc y = y_pos; width = percent*screen_w/100; height = percent*screen_h/100; - shadow = has_shadow; + shadow = shadow_mode; shadow_w = SHADOW_OFFSET; col_frame = color_frame; col_body = color_body; @@ -73,7 +73,7 @@ CComponentsPIP::CComponentsPIP( const int x_pos, const int y_pos, const int perc CComponentsPIP::~CComponentsPIP() { hide(); - videoDecoder->Pig(-1, -1, -1, -1); +// videoDecoder->Pig(-1, -1, -1, -1); } void CComponentsPIP::paint(bool do_save_bg) @@ -111,8 +111,8 @@ void CComponentsPIP::paint(bool do_save_bg) } -void CComponentsPIP::hide(bool no_restore) +void CComponentsPIP::hide() { videoDecoder->Pig(-1, -1, -1, -1); - hideCCItem(no_restore); + CComponents::hide(); } diff --git a/src/gui/components/cc_item_tvpic.h b/src/gui/components/cc_item_tvpic.h index 280f6cb83..1ffc0ebe8 100644 --- a/src/gui/components/cc_item_tvpic.h +++ b/src/gui/components/cc_item_tvpic.h @@ -31,6 +31,7 @@ #endif #include "cc_base.h" +#include "cc_item.h" #include //! Sub class of CComponentsItem. Shows a mini tv box, similar to a PIP-Feature with current tv-channel. @@ -52,7 +53,7 @@ class CComponentsPIP : public CComponentsItem ///constructor: initialize of position like all other items with x and y values, but dimensions in percent CComponentsPIP( const int x_pos = 0, const int y_pos = 0, const int percent = 30, CComponentsForm *parent = NULL, - bool has_shadow = CC_SHADOW_OFF, + int shadow_mode = CC_SHADOW_OFF, fb_pixel_t color_frame = COL_BLACK, fb_pixel_t color_body = COL_BACKGROUND_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); ~CComponentsPIP(); @@ -66,7 +67,7 @@ class CComponentsPIP : public CComponentsItem ///show tv box void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); ///remove tv box from screen - void hide(bool no_restore = false); + void hide(); }; #endif diff --git a/src/gui/components/cc_text_screen.h b/src/gui/components/cc_text_screen.h new file mode 100644 index 000000000..afdbe9024 --- /dev/null +++ b/src/gui/components/cc_text_screen.h @@ -0,0 +1,44 @@ +/* + Based up Neutrino-GUI - Tuxbox-Project + Copyright (C) 2001 by Steffen Hehn 'McClean' + + Classes for generic GUI-related components. + Copyright (C) 2015, Thilo Graf 'dbt' + + License: GPL + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __CC_TXT_SCREEN__ +#define __CC_TXT_SCREEN__ + + +//! Sub class for CTextBox using CComponent classes. +/*! +This class contains flags or helpers to control CTextBox screen and paint handling and mostly used by +CComponentsText and its derivatives and should be implemented as heredity. +At the moment used in classes with text handlers. e.g. buttons, headers, ext text ... +*/ +class CCTextScreen +{ + protected: + ///allows to save bg screen behind caption within CTextBox object, default = false + bool cc_txt_save_screen; + + public: + CCTextScreen(){cc_txt_save_screen = false;}; +}; + +#endif diff --git a/src/gui/components/cc_timer.cpp b/src/gui/components/cc_timer.cpp index a2d30ec75..f7cbfa4ad 100644 --- a/src/gui/components/cc_timer.cpp +++ b/src/gui/components/cc_timer.cpp @@ -61,8 +61,8 @@ void* CComponentsTimer::initTimerThread(void *arg) while(timer) { timer->mutex.lock(); timer->OnTimer(); - mySleep(timer->tm_interval); timer->mutex.unlock(); + mySleep(timer->tm_interval); } return 0; @@ -79,36 +79,39 @@ bool CComponentsTimer::startTimer() if(!tm_thread) { int res = pthread_create (&tm_thread, NULL, initTimerThread, ptr) ; if (res != 0){ - dprintf(DEBUG_NORMAL,"[CComponentsTimer] [%s] pthread_create %s\n", __func__, strerror(errno)); + dprintf(DEBUG_NORMAL,"\033[33m[CComponentsTimer] [%s - %d] ERROR! pthread_create\033[0m\n", __func__, __LINE__); return false; } - dprintf(DEBUG_INFO,"[CComponentsTimer] [%s] timer thread [%lu] created with interval = %d\n", __func__, tm_thread, tm_interval); + if (res == 0){ + dprintf(DEBUG_INFO,"\033[33m[CComponentsTimer] [%s - %d] timer thread [%lu] created with interval = %d\033[0m\n", __func__, __LINE__, pthread_self(), tm_interval); + CNeutrinoApp::getInstance()->OnBeforeRestart.connect(sl); + }else{ + dprintf(DEBUG_NORMAL, "\033[33m[CComponentsTimer] [%s - %d] ERROR! pthread_create\033[0m\n", __func__, __LINE__); + } } - - //ensure kill of thread on any restart of neutrino - CNeutrinoApp::getInstance()->OnBeforeRestart.connect(sl); return true; } //stop ticking timer and kill thread, return true on succses bool CComponentsTimer::stopTimer() { - int thres = 0; if(tm_thread) { - thres = pthread_cancel(tm_thread); - dprintf(DEBUG_INFO,"[CComponentsTimer] [%s] waiting for timer thread terminate ...\n", __func__); + int thres = pthread_cancel(tm_thread); if (thres != 0) - dprintf(DEBUG_NORMAL,"[CComponentsTimer] [%s] pthread_cancel %s\n", __func__, strerror(errno)); - thres = pthread_join(tm_thread, NULL); - if (thres != 0) - dprintf(DEBUG_NORMAL, "[CComponentsTimer] [%s] pthread_join %s\n", __func__, strerror(errno)); - } - if (thres == 0){ - tm_thread = 0; - //ensure disconnect of unused slot - sl.disconnect(); - return true; - } + dprintf(DEBUG_NORMAL,"\033[33m[CComponentsTimer] [%s - %d] ERROR! pthread_cancel\033[0m\n", __func__, __LINE__); + thres = pthread_join(tm_thread, NULL); + + if (thres != 0) + dprintf(DEBUG_NORMAL, "\033[33m[CComponentsTimer] [%s - %d] ERROR! pthread_join\033[0m\n", __func__, __LINE__); + + if (thres == 0){ + tm_thread = 0; + //ensure disconnect of unused slot + sl.disconnect(); + dprintf(DEBUG_INFO,"\033[33m[CComponentsTimer] [%s] timer thread terminated ...\033[0m\n", __func__); + return true; + } + } return false; } diff --git a/src/gui/components/cc_timer.h b/src/gui/components/cc_timer.h index 5be4b252b..321a0b184 100644 --- a/src/gui/components/cc_timer.h +++ b/src/gui/components/cc_timer.h @@ -3,7 +3,7 @@ Copyright (C) 2001 by Steffen Hehn 'McClean' Classes for generic GUI-related components. - Copyright (C) 2013, Thilo Graf 'dbt' + Copyright (C) 2013-2015, Thilo Graf 'dbt' License: GPL diff --git a/src/gui/components/cc_types.h b/src/gui/components/cc_types.h index c861309d1..8636ab679 100644 --- a/src/gui/components/cc_types.h +++ b/src/gui/components/cc_types.h @@ -38,7 +38,8 @@ class CComponentsScrollBar; ///cc item types typedef enum { - CC_ITEMTYPE_BASE, + CC_ITEMTYPE_GENERIC, + CC_ITEMTYPE_ITEM, CC_ITEMTYPE_PICTURE, CC_ITEMTYPE_TEXT, CC_ITEMTYPE_TEXT_INFOBOX, @@ -67,8 +68,9 @@ typedef enum }CC_ITEMTYPES_T; //required typedefs -typedef struct comp_fbdata_t +typedef struct cc_fbdata_t { + bool enabled; int fbdata_type; int x; int y; @@ -76,32 +78,48 @@ typedef struct comp_fbdata_t int dy; fb_pixel_t color; int r; + int rtype; int frame_thickness; fb_pixel_t* pixbuf; + gradientData_t *gradient_data; void * data; -} comp_fbdata_struct_t; + bool is_painted; +} cc_fbdata_struct_t; -//fb data object types +//fb data object layer types typedef enum { CC_FBDATA_TYPE_BGSCREEN, CC_FBDATA_TYPE_BOX, CC_FBDATA_TYPE_SHADOW_BOX, CC_FBDATA_TYPE_FRAME, - CC_FBDATA_TYPE_LINE, CC_FBDATA_TYPE_BACKGROUND, CC_FBDATA_TYPES }FBDATA_TYPES; -typedef struct comp_screen_data_t +//fb color gradient types +typedef enum +{ + CC_COLGRAD_OFF, //no gradient + CC_COLGRAD_LIGHT_2_DARK, //normal one color + CC_COLGRAD_DARK_2_LIGHT, //changed + CC_COLGRAD_COL_A_2_COL_B, //gradient from color A to color B + CC_COLGRAD_COL_B_2_COL_A, //gradient from color B to color A + CC_COLGRAD_COL_LIGHT_DARK_LIGHT,//gradient from color A to B to A + CC_COLGRAD_COL_DARK_LIGHT_DARK, //gradient from color B to A to B + + CC_COLGRAD_TYPES +}COLOR_GRADIENT_TYPES; + +typedef struct cc_screen_data_t { int x; int y; int dx; int dy; fb_pixel_t* pixbuf; -} comp_screen_data_struct_t; +} cc_screen_data_struct_t; //combination of rc messages with related icon typedef struct msg_list_t @@ -136,7 +154,7 @@ enum CC_ITEMBOX_CLOCK }; -typedef struct comp_element_data_t +typedef struct cc_element_data_t { int type; int align; @@ -147,27 +165,31 @@ typedef struct comp_element_data_t int height; void* handler1; void* handler2; -}comp_element_data_struct_t; +}cc_element_data_struct_t; -//text lebel types -typedef struct locale_ext_txt_t +//text label types +typedef struct cc_locale_ext_txt_t { neutrino_locale_t label_text; neutrino_locale_t text; Font* font; -} locale_ext_txt_struct_t; +} cc_locale_ext_txt_struct_t; -typedef struct string_ext_txt_t +typedef struct cc_string_ext_txt_t { std::string label_text; std::string text; Font* font; -} string_ext_txt_struct_t; +} cc_string_ext_txt_struct_t; #define CC_WIDTH_MIN 16 #define CC_HEIGHT_MIN 16 -#define CC_SHADOW_ON true -#define CC_SHADOW_OFF false + +#define CC_SHADOW_OFF 0 +#define CC_SHADOW_ON 1 +#define CC_SHADOW_RIGHT 2 +#define CC_SHADOW_BOTTOM 4 + #define CC_SAVE_SCREEN_YES true #define CC_SAVE_SCREEN_NO false diff --git a/src/gui/infoclock.cpp b/src/gui/infoclock.cpp index be6cb15a3..b41da69b4 100644 --- a/src/gui/infoclock.cpp +++ b/src/gui/infoclock.cpp @@ -4,7 +4,7 @@ Info Clock Window based up CComponentsFrmClock - Copyright (C) 2013, Thilo Graf 'dbt' + Copyright (C) 2013-2015, Thilo Graf 'dbt' Copyright (C) 2013, Michael Liebmann 'micha-bbg' License: GPL @@ -36,9 +36,9 @@ -CInfoClock::CInfoClock():CComponentsFrmClock( 0, 0, 0, 50, "%H:%M:%S", true, NULL, CC_SHADOW_ON, COL_LIGHT_GRAY, COL_MENUCONTENT_PLUS_0,COL_MENUCONTENTDARK_PLUS_0) +CInfoClock::CInfoClock():CComponentsFrmClock( 1, 1, NULL, "%H:%M:%S", NULL, false, 1, NULL, CC_SHADOW_ON, COL_LIGHT_GRAY, COL_MENUCONTENT_PLUS_0,COL_MENUCONTENTDARK_PLUS_0) { - initVarInfoClock(); + initCCLockItems(); } CInfoClock* CInfoClock::getInstance() @@ -49,68 +49,62 @@ CInfoClock* CInfoClock::getInstance() return InfoClock; } -void CInfoClock::initVarInfoClock() +void CInfoClock::initCCLockItems() { - Init(); -} - -void CInfoClock::Init() -{ - static int oldSize = 0; - if (oldSize != g_settings.infoClockFontSize) { - oldSize = g_settings.infoClockFontSize; - setClockFontSize(g_settings.infoClockFontSize); - } + paint_bg = g_settings.infoClockBackground; //use current theme colors - syncSysColors(); + setColorAll(COL_MENUCONTENT_PLUS_6, COL_MENUCONTENT_PLUS_0, COL_MENUCONTENTDARK_PLUS_0); //set text color - if (g_settings.infoClockBackground) - setTextColor(COL_MENUCONTENT_TEXT); - else - setTextColor(COL_INFOCLOCK_TEXT); - - paint_bg = true; - if (g_settings.infoClockBackground) + if (paint_bg){ + cl_col_text = COL_MENUCONTENT_TEXT; setColorBody(COL_MENUCONTENT_PLUS_0); - else + }else{ + cl_col_text = COL_INFOCLOCK_TEXT; setColorBody(COL_BACKGROUND_PLUS_0); - - setShadowOnOff(g_settings.infoClockBackground); + } if (g_settings.infoClockSeconds) setClockFormat("%H:%M:%S"); - else { - setClockFormat("%H:%M"); - setClockBlink("%H %M"); - } + else + setClockFormat("%H:%M", "%H %M"); - int x_old = x, y_old = y, width_old = width, height_old = height; - CVolumeHelper::getInstance()->refresh(cl_font); - CVolumeHelper::getInstance()->getInfoClockDimensions(&x, &y, &width, &height); - if ((x_old != x) || (y_old != y) || (width_old != width) || (height_old != height)) - clear(); + //set height, NOTE: height is strictly bound to settings + if (g_settings.infoClockFontSize != height){ + height = g_settings.infoClockFontSize; + int dx = 0; + int dy = height; + setClockFont(*CNeutrinoFonts::getInstance()->getDynFont(dx, dy, cl_format_str, cl_font_style)); + } // set corner radius depending on clock height corner_rad = (g_settings.rounded_corners) ? std::max(height/10, CORNER_RADIUS_SMALL) : 0; - initCCLockItems(); + CComponentsFrmClock::initCCLockItems(); + CVolumeHelper::getInstance()->refresh(cl_font); + CVolumeHelper::getInstance()->getInfoClockDimensions(&x, &y, &width, &height); } void CInfoClock::ClearDisplay() { - kill(); - Init(); + bool run = isRun(); + this->kill(); + clearSavedScreen(); + initCCLockItems(); + //provokes full repaint for next activation, otherwise clock segments only repaints on changed content + clear(); + if (run) + Start(); } -bool CInfoClock::StartClock() +bool CInfoClock::StartInfoClock() { - Init(); + initCCLockItems(); return Start(); } -bool CInfoClock::StopClock() +bool CInfoClock::StopInfoClock() { bool ret = Stop(); kill(); @@ -123,13 +117,22 @@ bool CInfoClock::enableInfoClock(bool enable) bool ret = false; if (g_settings.mode_clock) { if (enable) { - if (!paintClock) - ret = StartClock(); + if (isBlocked()) //blocked + ret = StartInfoClock(); } else { - if (paintClock) - ret = StopClock(); + if (!isBlocked()) //unblocked + ret = StopInfoClock(); } } return ret; } + +//switching clock on or off depends of current displayed or not +void CInfoClock::switchClockOnOff() +{ + if(g_settings.mode_clock) + g_settings.mode_clock = false; + else + g_settings.mode_clock = true; +} diff --git a/src/gui/infoclock.h b/src/gui/infoclock.h index 5fb6f315b..e8d48c5fe 100644 --- a/src/gui/infoclock.h +++ b/src/gui/infoclock.h @@ -4,7 +4,7 @@ Info Clock Window based up CComponentsFrmClock - Copyright (C) 2013, Thilo Graf 'dbt' + Copyright (C) 2013-2015, Thilo Graf 'dbt' Copyright (C) 2013, Michael Liebmann 'micha-bbg' License: GPL @@ -34,21 +34,21 @@ class CInfoClock : public CComponentsFrmClock { - protected: - void initVarInfoClock(); private: - void Init(); + void initCCLockItems(); public: CInfoClock(); // ~CInfoClock(); // inherited from CComponentsFrmClock static CInfoClock* getInstance(); - bool StartClock(); - bool StopClock(); - bool enableInfoClock(bool enable); + bool StartInfoClock(); + bool StopInfoClock(); + bool enableInfoClock(bool enable = true); + bool disableInfoClock() {return enableInfoClock(false);} void ClearDisplay(); + void setHeight(const int){}//NOTE: dummy member, height is strictly bound to settings - bool getStatus(void) { return paintClock; } + static void switchClockOnOff(); }; #endif diff --git a/src/gui/streaminfo2.cpp b/src/gui/streaminfo2.cpp index f166f6e50..9fa937c87 100644 --- a/src/gui/streaminfo2.cpp +++ b/src/gui/streaminfo2.cpp @@ -264,7 +264,7 @@ int CStreamInfo2::doSignalStrengthLoop () void CStreamInfo2::hide () { - pip->hide(true); + pip->hide(); frameBuffer->paintBackgroundBoxRel (0, 0, max_width, max_height); } diff --git a/src/gui/test_menu.cpp b/src/gui/test_menu.cpp index 109155f87..4cce0bbe6 100644 --- a/src/gui/test_menu.cpp +++ b/src/gui/test_menu.cpp @@ -495,9 +495,12 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) header->addContextButton(NEUTRINO_ICON_BUTTON_RED); header->addContextButton(CComponentsHeader::CC_BTN_HELP | CComponentsHeader::CC_BTN_EXIT | CComponentsHeader::CC_BTN_MENU); } - else //For existing instances it's recommended to remove old button icons before add new buttons, + else{ //For existing instances it's recommended to remove old button icons before add new buttons, //otherwise icons will be appended to already existant icons, alternatively use the setContextButton() methode header->removeContextButtons(); + //enable clock in header with default format + header->enableClock(true, "%H:%M", "%H %M", true); + } // example to manipulate header items // header->setFrameThickness(5); @@ -534,10 +537,13 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) // header->insertCCItem(1, logo); //replace text with logo - if (!header->isPainted()) + if (!header->isPainted()){ header->paint(); - else + } + else{ header->hide(); + } + return res; } else if (actionKey == "footer"){ @@ -629,7 +635,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) window->setWindowCaption("|.....................|"); window->setDimensionsAll(50, 50, 500, 500); window->setWindowIcon(NEUTRINO_ICON_INFO); - window->setShadowOnOff(true); + window->enableShadow(); CComponentsShapeCircle *c10 = new CComponentsShapeCircle(0, 0, 28); CComponentsShapeCircle *c11 = new CComponentsShapeCircle(0, CC_APPEND, 28); @@ -672,8 +678,8 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) } else if (actionKey == "running_clock"){ if (clock_r == NULL){ - clock_r = new CComponentsFrmClock(100, 50, 0, 50, "%H.%M:%S", true); - clock_r->setClockFont(SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME); + clock_r = new CComponentsFrmClock(100, 50, NULL, "%H.%M:%S", NULL, true); + clock_r->setClockFont(g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]); clock_r->setClockIntervall(1); // clock_r->doPaintBg(false); } @@ -684,7 +690,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) } else { if (clock_r->Stop()){ - clock_r->hide(); + clock_r->kill(); delete clock_r; clock_r = NULL; return menu_return::RETURN_EXIT_ALL; @@ -693,8 +699,8 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) } else if (actionKey == "clock"){ if (clock == NULL){ - clock = new CComponentsFrmClock(100, 50, 0, 50, "%H:%M", false); - clock->setClockFont(SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME); + clock = new CComponentsFrmClock(100, 50, NULL, "%d.%m.%Y-%H:%M"); + clock->setClockFont(g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]); } if (!clock->isPainted()) diff --git a/src/gui/timeosd.cpp b/src/gui/timeosd.cpp index 57f136eb4..621eef062 100644 --- a/src/gui/timeosd.cpp +++ b/src/gui/timeosd.cpp @@ -36,41 +36,46 @@ -CTimeOSD::CTimeOSD():CComponentsFrmClock( 0, 0, 0, 50, "%H:%M:%S", false, NULL, CC_SHADOW_ON, COL_LIGHT_GRAY, COL_MENUCONTENT_PLUS_0,COL_MENUCONTENTDARK_PLUS_0) +CTimeOSD::CTimeOSD():CComponentsFrmClock( 1, 1, NULL, "%H:%M:%S", NULL, false, 1, NULL, CC_SHADOW_ON, COL_LIGHT_GRAY, COL_MENUCONTENT_PLUS_0,COL_MENUCONTENTDARK_PLUS_0) { Init(); } void CTimeOSD::Init() { - static int oldSize = 0; - - m_mode = MODE_HIDE; - m_time_show = 0; - - if (oldSize != g_settings.infoClockFontSize) { - oldSize = g_settings.infoClockFontSize; - setClockFontSize(g_settings.infoClockFontSize); - } - - //use current theme colors - syncSysColors(); - paint_bg = g_settings.infoClockBackground; - setClockFormat("%H:%M:%S"); + //use current theme colors + setColorAll(COL_MENUCONTENT_PLUS_6, COL_MENUCONTENT_PLUS_0, COL_MENUCONTENTDARK_PLUS_0); - int x_old = x, y_old = y, width_old = width, height_old = height; - CVolumeHelper::getInstance()->refresh(cl_font); - CVolumeHelper::getInstance()->getTimeDimensions(&x, &y, &width, &height); - if ((x_old != x) || (y_old != y) || (width_old != width) || (height_old != height)) - clear(); + //set text color + if (paint_bg){ + cl_col_text = COL_MENUCONTENT_TEXT; + setColorBody(COL_MENUCONTENT_PLUS_0); + }else{ + cl_col_text = COL_INFOCLOCK_TEXT; + setColorBody(COL_BACKGROUND_PLUS_0); + } + + if (g_settings.infoClockSeconds) + setClockFormat("%H:%M:%S"); + else + setClockFormat("%H:%M", "%H %M"); + + //set height, NOTE: height is strictly bound to settings + if (g_settings.infoClockFontSize != height){ + height = g_settings.infoClockFontSize; + int dx = 0; + int dy = height; + setClockFont(*CNeutrinoFonts::getInstance()->getDynFont(dx, dy, cl_format_str, cl_font_style)); + } // set corner radius depending on clock height corner_rad = (g_settings.rounded_corners) ? std::max(height/10, CORNER_RADIUS_SMALL) : 0; - initCCLockItems(); - + CComponentsFrmClock::initCCLockItems(); + CVolumeHelper::getInstance()->refresh(cl_font); + CVolumeHelper::getInstance()->getTimeDimensions(&x, &y, &width, &height); timescale.setType(CProgressBar::PB_TIMESCALE); } @@ -85,13 +90,10 @@ CTimeOSD::~CTimeOSD() void CTimeOSD::initTimeString() { struct tm t; - if (m_mode == MODE_DESC) { - char tt[20]; - strftime(tt, sizeof(tt), cl_format_str, gmtime_r(&m_time_show, &t)); - snprintf(cl_timestr, sizeof(cl_timestr), "-%s", tt); - } - else - strftime(cl_timestr, sizeof(cl_timestr), cl_format_str, gmtime_r(&m_time_show, &t)); + toggleFormat(); + if (m_mode == MODE_DESC) + cl_format = "-" + cl_format; + strftime((char*) &cl_timestr, sizeof(cl_timestr), cl_format.c_str(), gmtime_r(&m_time_show, &t)); } void CTimeOSD::show(time_t time_show, bool force) @@ -101,7 +103,7 @@ void CTimeOSD::show(time_t time_show, bool force) return; m_time_show = time_show; - syncSysColors(); + setColorAll(COL_MENUCONTENT_PLUS_6, COL_MENUCONTENT_PLUS_0, COL_MENUCONTENTDARK_PLUS_0); //use current theme colors paint_bg = true; if (g_settings.infoClockBackground) @@ -109,7 +111,7 @@ void CTimeOSD::show(time_t time_show, bool force) else setColorBody(COL_BACKGROUND_PLUS_0); - setShadowOnOff(g_settings.infoClockBackground); + enableShadow(g_settings.infoClockBackground); paint(false); } @@ -124,7 +126,6 @@ void CTimeOSD::updatePos(int position, int duration) timescale.setProgress(x, y + height/4, width, height/2, percent, 100); timescale.paint(); - frameBuffer->blit(); } void CTimeOSD::update(int position, int duration) @@ -157,7 +158,6 @@ void CTimeOSD::switchMode(int position, int duration) break; case MODE_BAR: KillAndResetTimescale(); - frameBuffer->blit(); return; default: m_mode = MODE_ASC; diff --git a/src/gui/timerlist.cpp b/src/gui/timerlist.cpp index b65529220..906424103 100644 --- a/src/gui/timerlist.cpp +++ b/src/gui/timerlist.cpp @@ -870,8 +870,8 @@ void CTimerList::paintItem(int pos) void CTimerList::paintHead() { - CComponentsHeaderLocalized header(x, y, width, theight, LOCALE_TIMERLIST_NAME, NEUTRINO_ICON_TIMER); - header.setShadowOnOff(CC_SHADOW_ON); + CComponentsHeaderLocalized header(x, y, width, theight, LOCALE_TIMERLIST_NAME, NEUTRINO_ICON_TIMER, CComponentsHeader::CC_BTN_EXIT, NULL, CC_SHADOW_ON); + header.enableClock(true, "%d.%m.%Y %H:%M"); header.paint(CC_SAVE_SCREEN_NO); } diff --git a/src/gui/volumebar.cpp b/src/gui/volumebar.cpp index 66e6a5804..dad43bedc 100644 --- a/src/gui/volumebar.cpp +++ b/src/gui/volumebar.cpp @@ -248,13 +248,6 @@ void CVolumeBar::paintVolScale() } -//final paint -void CVolumeBar::paint(bool do_save_bg) -{ - //paint form - paintForm(do_save_bg); -} - // CVolumeHelper #################################################################################################### @@ -270,7 +263,7 @@ CVolumeHelper::CVolumeHelper() Init(); } -void CVolumeHelper::Init(Font** font) +void CVolumeHelper::Init(Font* font) { x = frameBuffer->getScreenX() + h_spacer; @@ -283,11 +276,11 @@ void CVolumeHelper::Init(Font** font) initInfoClock(font); } -void CVolumeHelper::initInfoClock(Font** font) +void CVolumeHelper::initInfoClock(Font* font) { if (clock_font == NULL){ if (font == NULL) { - clock_font = &g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]; + clock_font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]; } else clock_font = font; @@ -296,10 +289,10 @@ void CVolumeHelper::initInfoClock(Font** font) if (font != NULL) clock_font = font; } - digit_offset = (*clock_font)->getDigitOffset(); - digit_h = (*clock_font)->getDigitHeight(); - int t1 = (*clock_font)->getMaxDigitWidth(); - int t2 = (*clock_font)->getRenderWidth(":"); + digit_offset = (clock_font)->getDigitOffset(); + digit_h = (clock_font)->getDigitHeight(); + int t1 = (clock_font)->getMaxDigitWidth(); + int t2 = (clock_font)->getRenderWidth(":"); clock_dy = digit_h + (int)((float)digit_offset * 1.3); if (g_settings.infoClockSeconds) clock_dx = t1*7 + t2*2; @@ -365,7 +358,7 @@ int CVolumeHelper::getInfoClockX() return clock_ax; } -void CVolumeHelper::refresh(Font** font) +void CVolumeHelper::refresh(Font* font) { Init(font); } diff --git a/src/gui/volumebar.h b/src/gui/volumebar.h index 2ec76ddbb..02d8a378e 100644 --- a/src/gui/volumebar.h +++ b/src/gui/volumebar.h @@ -92,7 +92,6 @@ class CVolumeBar : public CComponentsForm // ~CVolumeBar(); inherited from CComponentsForm void repaintVolScale(); - void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); }; @@ -106,13 +105,13 @@ class CVolumeHelper int icon_width, icon_height, digit_width; int h_spacer, v_spacer; int vol_ay, vol_height; - Font** clock_font; + Font* clock_font; CFrameBuffer *frameBuffer; - void Init(Font** font=NULL); + void Init(Font* font=NULL); void initVolBarSize(); void initMuteIcon(); - void initInfoClock(Font** font); + void initInfoClock(Font* font); public: @@ -130,7 +129,7 @@ class CVolumeHelper void getTimeDimensions(int *_x, int *_y, int *w, int *h) { *_x = time_ax; *_y = clock_ay; *w = time_dx; *h = clock_dy; } void getVolBarDimensions(int *_y, int *_dy) { *_y = vol_ay; *_dy = vol_height; } void setMuteIconCorrY(int corr) { mute_corrY = corr; } - void refresh(Font** font=NULL); + void refresh(Font* font=NULL); }; #endif diff --git a/src/gui/widget/progresswindow.cpp b/src/gui/widget/progresswindow.cpp index 784245151..8e992cf1c 100644 --- a/src/gui/widget/progresswindow.cpp +++ b/src/gui/widget/progresswindow.cpp @@ -33,7 +33,7 @@ #include CProgressWindow::CProgressWindow(CComponentsForm *parent) -: CComponentsWindow(0, 0, 700, 200, string(), NEUTRINO_ICON_INFO, NULL, parent) +: CComponentsWindow(0, 0, 700, 200, string(), NEUTRINO_ICON_INFO, parent, CC_SHADOW_ON) { Init(); } @@ -186,9 +186,9 @@ unsigned int CProgressWindow::getGlobalStatus(void) return global_progress; } -void CProgressWindow::hide(bool no_restore) +void CProgressWindow::hide() { - CComponentsWindow::hide(no_restore); + CComponentsWindow::hide(); } int CProgressWindow::exec(CMenuTarget* parent, const std::string & /*actionKey*/) diff --git a/src/gui/widget/progresswindow.h b/src/gui/widget/progresswindow.h index 44350a9ee..6b8ff9e72 100644 --- a/src/gui/widget/progresswindow.h +++ b/src/gui/widget/progresswindow.h @@ -45,7 +45,7 @@ class CProgressWindow : public CComponentsWindow, public CMenuTarget CProgressWindow(CComponentsForm *parent = NULL); void setTitle(const neutrino_locale_t title); - virtual void hide(bool no_restore = false); + virtual void hide(); virtual int exec( CMenuTarget* parent, const std::string & actionKey ); diff --git a/src/system/debug.h b/src/system/debug.h index 62ea60732..40cba3863 100644 --- a/src/system/debug.h +++ b/src/system/debug.h @@ -24,7 +24,7 @@ #ifndef __neutrino_debug__ #define __neutrino_debug__ - +#include extern int debug; enum From 86b4c81cab9a865fd9eb95307ae728d5607d0582 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 19 Nov 2015 15:57:38 +0100 Subject: [PATCH 009/110] CBEChannelWidget/CBEChannelSelectWidget: remove setShadowOnOff() Name and function was changed --- src/gui/bedit/bouqueteditor_channels.cpp | 15 +++++++++++---- src/gui/bedit/bouqueteditor_chanselect.cpp | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/bedit/bouqueteditor_channels.cpp b/src/gui/bedit/bouqueteditor_channels.cpp index 834b0a263..5c0ae0b72 100644 --- a/src/gui/bedit/bouqueteditor_channels.cpp +++ b/src/gui/bedit/bouqueteditor_channels.cpp @@ -252,11 +252,18 @@ void CBEChannelWidget::initItem2DetailsLine (int pos, int /*ch_index*/) //infobox if (ibox == NULL){ ibox = new CComponentsInfoBox(); - ibox->setDimensionsAll(x, ypos2, width, info_height); - ibox->setFrameThickness(2); - ibox->setCorner(RADIUS_LARGE); - ibox->setShadowOnOff(CC_SHADOW_OFF); } + + if (ibox->isPainted()) + ibox->hide(); + + ibox->setDimensionsAll(x, ypos2, width, info_height); + ibox->setFrameThickness(2); +#if 0 + ibox->paint(false,true); +#endif + ibox->setCorner(RADIUS_LARGE); + ibox->disableShadow(); } } diff --git a/src/gui/bedit/bouqueteditor_chanselect.cpp b/src/gui/bedit/bouqueteditor_chanselect.cpp index 0875d657b..2888bab7a 100644 --- a/src/gui/bedit/bouqueteditor_chanselect.cpp +++ b/src/gui/bedit/bouqueteditor_chanselect.cpp @@ -309,7 +309,7 @@ void CBEChannelSelectWidget::initItem2DetailsLine (int pos, int /*ch_index*/) ibox->setDimensionsAll(x, ypos2, width, info_height); ibox->setFrameThickness(2); ibox->setCorner(RADIUS_LARGE); - ibox->setShadowOnOff(CC_SHADOW_OFF); + ibox->disableShadow(); } } } From 523b273af8f8bce145973a4b8ed0d0a27b3df335 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 19 Nov 2015 15:59:48 +0100 Subject: [PATCH 010/110] Colors: init global color gradient implementation --- data/locale/deutsch.locale | 16 ++ data/locale/english.locale | 18 +- data/locale/nederlands.locale | 18 ++ data/locale/slovak.locale | 23 +- data/themes/Makefile.am | 1 + data/themes/Neutrino3.0.theme | 67 ++++++ src/gui/eventlist.cpp | 8 +- src/gui/infoviewer.cpp | 437 +++++++++++++++++++--------------- src/gui/infoviewer.h | 13 +- src/gui/infoviewer_bb.cpp | 126 ++++++---- src/gui/infoviewer_bb.h | 9 +- src/gui/osd_setup.cpp | 185 ++++++++++---- src/gui/osd_setup.h | 11 +- src/gui/themes.cpp | 61 +++-- src/neutrino.cpp | 39 ++- src/system/locals.h | 18 +- src/system/locals_intern.h | 18 +- src/system/settings.h | 18 +- 18 files changed, 725 insertions(+), 361 deletions(-) create mode 100644 data/themes/Neutrino3.0.theme diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index cbf4d6475..81fbb7983 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -290,10 +290,23 @@ clock_size_height Höhe der Anzeige clock_switch_off Uhr ausblenden clock_switch_on Uhr einblenden color.gradient Farbverlauf +color.gradient_a2b Farbe A zu B +color.gradient_b2a Farbe B zu A +color.gradient_d2l dunkel nach hell +color.gradient_dld dunkel hell dunkel +color.gradient_l2d hell nach dunkel +color.gradient_ldl hell dunkel hell +color.gradient_mode_direction Richtung +color.gradient_mode_direction_hor horizontal +color.gradient_mode_direction_ver vertikal +color.gradient_separator_enable Farbverlauf für Trennlinie colorchooser.alpha alpha colorchooser.blue blau colorchooser.green grün colorchooser.red rot +colorchooser.save Speichern +colormenu.advanced_mode_off Standard-Optionen +colormenu.advanced_mode_on Erweiterte Optionen colormenu.background Hintergrundfarbe colormenu.clock_textcolor Ziffernfarbe colormenu.contrast_fonts Schriftkontrast @@ -976,6 +989,8 @@ menu.hint_clock_seconds Legen Sie fest, ob die Sekunden angezeigt werden sollen menu.hint_clock_size Stellen Sie die Größe der Uhr ein menu.hint_clock_textcolor Konfigurieren Sie die Farbe der Ziffern menu.hint_color_gradient Schaltet Farbverläufe für verschiedene Menüelemente ein/aus +menu.hint_color_gradient_direction Richtung des Farbverlaufs festlegen +menu.hint_color_gradient_separator_enable Farbverlauf für Menü-Trennlinien aktivieren/deaktivieren menu.hint_colored_events Definiert, ob die aktuelle oder nächste Sendung in einer anderen Farbe dargestellt werden soll menu.hint_colored_events_textcolor Ändern Sie die Farbe für farbige Events in der Kanalliste und der Infobar menu.hint_colors Konfigurieren Sie die Menü-Farben @@ -1470,6 +1485,7 @@ miscsettings.infobar_disp_3 Logo, Kanalname [Signalbalken] miscsettings.infobar_disp_4 Logo, Kanalname [Kanalnummer] miscsettings.infobar_disp_5 Logo [Signalbalken] miscsettings.infobar_disp_6 Kanalnummer, Logo [Signalbalken] +miscsettings.infobar_gradient_body Farbverlauf EPG-Bereich miscsettings.infobar_gradient_bottom Farbverlauf unten miscsettings.infobar_gradient_top Farbverlauf oben miscsettings.infobar_logo_hdd_dir Logo-Verzeichnis diff --git a/data/locale/english.locale b/data/locale/english.locale index 4898ab4bd..160a18479 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -290,11 +290,23 @@ clock_size_height Display height clock_switch_off Clock off clock_switch_on Clock on color.gradient Color gradient -color.gradient_c2c Color to color gradient +color.gradient_a2b color A to B +color.gradient_b2a color B to A +color.gradient_d2l dark to light +color.gradient_dld dark light dark +color.gradient_l2d light to dark +color.gradient_ldl light dark light +color.gradient_mode_direction Direction +color.gradient_mode_direction_hor horizontal +color.gradient_mode_direction_ver vertical +color.gradient_separator_enable Color gradient separator line colorchooser.alpha alpha colorchooser.blue blue colorchooser.green green colorchooser.red red +colorchooser.save Save +colormenu.advanced_mode_off Default options +colormenu.advanced_mode_on Advanced options colormenu.background Background colormenu.clock_textcolor Digit color colormenu.contrast_fonts Contrast fonts @@ -977,7 +989,8 @@ menu.hint_clock_seconds Show time format with seconds menu.hint_clock_size Set the size of the info clock menu.hint_clock_textcolor Configure digit colors menu.hint_color_gradient Switches color gradients for various menu items on/off -menu.hint_color_gradient_c2c Switches smooth gradient between 2 colors and one-color gradient +menu.hint_color_gradient_direction Define direction of color gradient. +menu.hint_color_gradient_separator_enable Disable/enable color gradient for menu separator lines menu.hint_colored_events Use different color for current or next event menu.hint_colored_events_textcolor Change color for colored events in channellist and infobar menu.hint_colors Configure GUI colors @@ -1472,6 +1485,7 @@ miscsettings.infobar_disp_3 Logo, Channelname [Signal] miscsettings.infobar_disp_4 Logo, Channelname [Channelnumber] miscsettings.infobar_disp_5 Logo [Signal] miscsettings.infobar_disp_6 Channelnumber, Logo [Signal] +miscsettings.infobar_gradient_body Gradient EPG-area miscsettings.infobar_gradient_bottom Gradient bottom miscsettings.infobar_gradient_top Gradient top miscsettings.infobar_logo_hdd_dir Logo directory diff --git a/data/locale/nederlands.locale b/data/locale/nederlands.locale index 4556a00f2..3c1f70fbb 100644 --- a/data/locale/nederlands.locale +++ b/data/locale/nederlands.locale @@ -270,10 +270,23 @@ clock_size_height Display hoogte clock_switch_off klok uit clock_switch_on klok aan color.gradient Kleur gradient +color.gradient_a2b color A to B +color.gradient_a2b color B to A +color.gradient_d2l donker tot licht +color.gradient_dld donker licht donker +color.gradient_l2d licht tot donker +color.gradient_ldl licht donker licht +color.gradient_mode_direction Richting +color.gradient_mode_direction_hor horizontaal +color.gradient_mode_direction_ver vertikaal +color.gradient_separator_enable Gradiënt voor separator colorchooser.alpha Alpha colorchooser.blue Blauw colorchooser.green Groen colorchooser.red Rood +colorchooser.save Save +colormenu.advanced_mode_off Toon standaard opties +colormenu.advanced_mode_on Toon geavanceerde zoekopties colormenu.background Achtergrond colormenu.clock_textcolor Digit kleur colormenu.contrast_fonts Contrast lettertype @@ -928,6 +941,8 @@ menu.hint_clock_seconds Toon tijdsformaat met secondes menu.hint_clock_size Stel grootte van de info klok in menu.hint_clock_textcolor Configureer digit kleuren menu.hint_color_gradient Schakel kleur verloop van menu items aan/uit +menu.hint_color_gradient_direction Definieer de richting van kleurverloop. +menu.hint_color_gradient_separator_enable Uitschakelen/inschakelen kleurverloop voor menu separator lijnen menu.hint_colored_events Gebruik andere kleur voor huidige of volgende programma menu.hint_colored_events_textcolor Wijzig programma kleur voor gekleurde programma opties in kanalenlijst en infobalk. menu.hint_colors Configureer GUI-kleuren @@ -1399,6 +1414,9 @@ miscsettings.infobar_disp_3 Logo, Kanaalnaam [Signaal] miscsettings.infobar_disp_4 Logo, Kanaalnaam [Kanaalnummer] miscsettings.infobar_disp_5 Logo [Signaal] miscsettings.infobar_disp_6 Kanaalnummer, Logo [Signaal] +miscsettings.infobar_gradient_body Gradient EPG-area +miscsettings.infobar_gradient_bottom Gradient knoppenbalk beschikbaar +miscsettings.infobar_gradient_top Gradient top miscsettings.infobar_logo_hdd_dir Logo directory miscsettings.infobar_sat_display Satelliet weergeven op de infobalk miscsettings.infobar_show show Info wanneer EPG verandert diff --git a/data/locale/slovak.locale b/data/locale/slovak.locale index 46ca0c03b..d4b0cdc35 100644 --- a/data/locale/slovak.locale +++ b/data/locale/slovak.locale @@ -290,11 +290,21 @@ clock_size_height Výška zobrazenia clock_switch_off Skryť hodiny clock_switch_on Zobraziť hodiny color.gradient Farebný gradient -color.gradient_c2c Farba farebného gradienta +color.gradient_a2b color A to B +color.gradient_b2a color B to A +color.gradient_d2l dark nach light +color.gradient_dld dark light dark +color.gradient_l2d light to dark +color.gradient_ldl light dark light +color.gradient_mode_direction Smer +color.gradient_mode_direction_hor horizontálne +color.gradient_mode_direction_ver vertikálne +color.gradient_separator_enable Gradient pre Separator colorchooser.alpha Priehľadnosť colorchooser.blue Modrý colorchooser.green Zelený colorchooser.red Červený +colorchooser.save Save colormenu.background Pozadie colormenu.clock_textcolor Farba čílic colormenu.contrast_fonts Kontrast písma @@ -975,9 +985,8 @@ menu.hint_clock_seconds Zobraenie formátu času so sekundami menu.hint_clock_size Nastavenie veľkosti informačných hodín. menu.hint_clock_textcolor Nastavenie ferieb číslic menu.hint_color_gradient Prepne farebné prechody pre rôzne položky ponuky Zap/Vyp -menu.hint_color_gradient_c2c Prepne prechody medzi 2 farbami a jednofarebným gradientom -menu.hint_colored_events Použije inú farbu pre aktuálnu alebo ďaľšiu udalosť -menu.hint_colored_events_textcolor Zmena farby pre farebné udalosti v zozname kanálov a infolištu +menu.hint_color_gradient_direction Definujte smer farebného prechodu. +menu.hint_color_gradient_separator_enable Povoliť/zakázať farebný gradient pre menu oddeľovacích liniek menu.hint_colors Konfigurácia farieb GUI menu.hint_content_back Zmena farby podkladu GUI okna menu.hint_content_textcolor Zmena farby textu GUI okna @@ -1470,8 +1479,10 @@ miscsettings.infobar_disp_3 Logo+názov kanála+signál miscsettings.infobar_disp_4 Logo+názov+číslo kanála miscsettings.infobar_disp_5 Logo+signál miscsettings.infobar_disp_6 Logo+číslo kanála+signál -miscsettings.infobar_gradient_bottom Spodok gradientu -miscsettings.infobar_gradient_top Vrch gradientu +miscsettings.infobar_disp_log len Logo +miscsettings.infobar_gradient_body Gradient EPG-area +miscsettings.infobar_gradient_bottom Gradient buttobar +miscsettings.infobar_gradient_top Gradient top miscsettings.infobar_logo_hdd_dir Adresár loga miscsettings.infobar_sat_display Zobrazenie satelitu v stavovom riadku miscsettings.infobar_show Zobraziť Info pri zmene EPG diff --git a/data/themes/Makefile.am b/data/themes/Makefile.am index 3e35742c0..c94cf8815 100644 --- a/data/themes/Makefile.am +++ b/data/themes/Makefile.am @@ -9,6 +9,7 @@ install_DATA = \ Gray.theme \ Grey-Blue.theme \ MonoChrom.theme \ + Neutrino3.0.theme \ Olive.theme \ Red.theme \ VirginMedia.theme diff --git a/data/themes/Neutrino3.0.theme b/data/themes/Neutrino3.0.theme new file mode 100644 index 000000000..69793b23e --- /dev/null +++ b/data/themes/Neutrino3.0.theme @@ -0,0 +1,67 @@ +clock_Digit_alpha=0 +clock_Digit_blue=100 +clock_Digit_green=100 +clock_Digit_red=100 +colored_events_alpha=0 +colored_events_blue=0 +colored_events_channellist=2 +colored_events_green=70 +colored_events_infobar=2 +colored_events_red=95 +infobar_Text_alpha=0 +infobar_Text_blue=100 +infobar_Text_green=100 +infobar_Text_red=100 +infobar_alpha=20 +infobar_blue=47 +infobar_casystem_alpha=8 +infobar_casystem_blue=54 +infobar_casystem_green=10 +infobar_casystem_red=4 +infobar_gradient_body=2 +infobar_gradient_body_direction=1 +infobar_gradient_bottom=1 +infobar_gradient_bottom_direction=1 +infobar_gradient_top=1 +infobar_gradient_top_direction=1 +infobar_green=4 +infobar_red=0 +menu_ButtonBar_gradient=0 +menu_ButtonBar_gradient_direction=1 +menu_Content_Selected_Text_alpha=0 +menu_Content_Selected_Text_blue=0 +menu_Content_Selected_Text_green=0 +menu_Content_Selected_Text_red=0 +menu_Content_Selected_alpha=20 +menu_Content_Selected_blue=100 +menu_Content_Selected_green=55 +menu_Content_Selected_red=25 +menu_Content_Text_alpha=0 +menu_Content_Text_blue=100 +menu_Content_Text_green=100 +menu_Content_Text_red=100 +menu_Content_alpha=20 +menu_Content_blue=41 +menu_Content_green=5 +menu_Content_inactive_Text_alpha=0 +menu_Content_inactive_Text_blue=85 +menu_Content_inactive_Text_green=70 +menu_Content_inactive_Text_red=55 +menu_Content_inactive_alpha=20 +menu_Content_inactive_blue=35 +menu_Content_inactive_green=15 +menu_Content_inactive_red=0 +menu_Content_red=0 +menu_Head_Text_alpha=0 +menu_Head_Text_blue=0 +menu_Head_Text_green=70 +menu_Head_Text_red=95 +menu_Head_alpha=0 +menu_Head_blue=35 +menu_Head_gradient=1 +menu_Head_gradient_direction=1 +menu_Head_green=6 +menu_Head_red=0 +menu_Hint_gradient=2 +menu_Hint_gradient_direction=1 +menu_Separator_gradient_enable=1 diff --git a/src/gui/eventlist.cpp b/src/gui/eventlist.cpp index 1341b5457..49f76757d 100644 --- a/src/gui/eventlist.cpp +++ b/src/gui/eventlist.cpp @@ -877,7 +877,7 @@ void CEventList::paintHead(t_channel_id _channel_id, std::string _channelname, s int font_lr = SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMLARGE; CComponentsFrmChain header(x, y, full_width, theight); - header.enableColBodyGradient(g_settings.theme.menu_Head_gradient); + header.enableColBodyGradient(g_settings.theme.menu_Head_gradient, COL_MENUCONTENT_PLUS_0, g_settings.theme.menu_Head_gradient_direction); header.setCorner(RADIUS_LARGE, CORNER_TOP); int x_off = 10; @@ -905,19 +905,19 @@ void CEventList::paintHead(t_channel_id _channel_id, std::string _channelname, s } else { header.removeCCItem(midLogo); //remove/destroy logo object, if it is not available - CComponentsText *midText = new CComponentsText(CC_CENTERED, CC_CENTERED, mid_width, theight, _channelname, CTextBox::CENTER, g_Font[font_mid], &header, CC_SHADOW_OFF, COL_MENUHEAD_TEXT); + CComponentsText *midText = new CComponentsText(CC_CENTERED, CC_CENTERED, mid_width, theight, _channelname, CTextBox::CENTER, g_Font[font_mid], CComponentsText::FONT_STYLE_REGULAR, &header, CC_SHADOW_OFF, COL_MENUHEAD_TEXT); midText->doPaintBg(false); } if (!_channelname_prev.empty()) { - CComponentsText *lText = new CComponentsText(x_off, CC_CENTERED, side_width, theight, _channelname_prev, CTextBox::NO_AUTO_LINEBREAK, g_Font[font_lr], &header, CC_SHADOW_OFF, COL_MENUHEAD_TEXT); + CComponentsText *lText = new CComponentsText(x_off, CC_CENTERED, side_width, theight, _channelname_prev, CTextBox::NO_AUTO_LINEBREAK, g_Font[font_lr], CComponentsText::FONT_STYLE_REGULAR, &header, CC_SHADOW_OFF, COL_MENUHEAD_TEXT); lText->doPaintBg(false); } if (!_channelname_next.empty()) { int name_w = std::min(g_Font[font_lr]->getRenderWidth(_channelname_next), side_width); int x_pos = full_width - name_w - x_off; - CComponentsText *rText = new CComponentsText(x_pos, CC_CENTERED, name_w, theight, _channelname_next, CTextBox::NO_AUTO_LINEBREAK, g_Font[font_lr], &header, CC_SHADOW_OFF, COL_MENUHEAD_TEXT); + CComponentsText *rText = new CComponentsText(x_pos, CC_CENTERED, name_w, theight, _channelname_next, CTextBox::NO_AUTO_LINEBREAK, g_Font[font_lr], CComponentsText::FONT_STYLE_REGULAR, &header, CC_SHADOW_OFF, COL_MENUHEAD_TEXT); rText->doPaintBg(false); } diff --git a/src/gui/infoviewer.cpp b/src/gui/infoviewer.cpp index 90c9add6b..c56d34cd4 100644 --- a/src/gui/infoviewer.cpp +++ b/src/gui/infoviewer.cpp @@ -83,7 +83,6 @@ extern CInfoClock *InfoClock; #define LEFT_OFFSET 5 - event_id_t CInfoViewer::last_curr_id = 0, CInfoViewer::last_next_id = 0; static bool sortByDateTime (const CChannelEvent& a, const CChannelEvent& b) @@ -96,8 +95,9 @@ extern bool timeset; CInfoViewer::CInfoViewer () : fader(g_settings.theme.infobar_alpha) { - sigscale = NULL; - snrscale = NULL; + sigbox = NULL; + header = numbox = body = rec = NULL; + txt_cur_start = txt_cur_event = txt_cur_event_rest = txt_next_start = txt_next_event = txt_next_in = NULL; timescale = NULL; clock = NULL; frameBuffer = CFrameBuffer::getInstance(); @@ -111,7 +111,7 @@ CInfoViewer::CInfoViewer () ChanWidth = 0; ChanHeight = 0; time_width = 0; - time_height = 0; + time_height = header_height = 0; lastsnr = 0; lastsig = 0; lasttime = 0; @@ -126,12 +126,7 @@ CInfoViewer::CInfoViewer () CInfoViewer::~CInfoViewer() { - delete sigscale; - delete snrscale; - delete timescale; - delete infoViewerBB; - delete infobar_txt; - delete clock; + ResetModules(); } void CInfoViewer::Init() @@ -150,11 +145,11 @@ void CInfoViewer::Init() SDT_freq_update = false; /* maybe we should not tie this to the blinkenlights settings? */ - infoViewerBB->setBBOffset(); + infoViewerBB->initBBOffset(); /* after font size changes, Init() might be called multiple times */ changePB(); - casysChange = g_settings.casystem_display; + casysChange = g_settings.infobar_casystem_display; channellogoChange = g_settings.infobar_show_channellogo; current_channel_id = CZapit::getInstance()->GetCurrentChannelID();; @@ -174,14 +169,14 @@ void CInfoViewer::Init() | | _recording icon _progress bar BoxStartY---+-----------+ | | | | | * #######____ - | | |-------------------------------------------+--+-ChanNameY - | | | Channelname | | - ChanHeight--+-----------+ | | - | | InfoHeightY - |01:23 Current Event | | - |02:34 Next Event | | - | | | - BoxEndY----+----------------------------------------------------+--+ + | | |-------------------------------------------+--+-ChanNameY-----+ + | | | Channelname (header) | clock | | header height | + ChanHeight--+-----------+-------------------------------------------+--+ | + | B---O---D---Y | |InfoHeightY + |01:23 Current Event | | + |02:34 Next Event | | + | | | + BoxEndY----+----------------------------------------------------+--+---------------+ | optional blinkenlights iconbar | bottom_bar_offset BBarY------+----------------------------------------------------+--+ | * red * green * yellow * blue ====== [DD][16:9]| InfoHeightY_Info @@ -221,7 +216,7 @@ void CInfoViewer::start () BoxEndY = g_settings.screen_EndY - 10 - infoViewerBB->InfoHeightY_Info - infoViewerBB->bottom_bar_offset; BoxStartY = BoxEndY - InfoHeightY - ChanHeight / 2; - ChanNameY = BoxStartY + (ChanHeight / 2) + SHADOW_OFFSET; //oberkante schatten? + ChanNameY = BoxStartY + (ChanHeight / 2)/* + SHADOW_OFFSET*/; //oberkante schatten? ChanInfoX = BoxStartX + (ChanWidth / 3); initClock(); @@ -229,18 +224,22 @@ void CInfoViewer::start () time_width = clock->getWidth(); } +void CInfoViewer::ResetPB() +{ + if (sigbox){ + delete sigbox; + sigbox = NULL; + } + + if (timescale){ + delete timescale; + timescale = NULL; + } +} + void CInfoViewer::changePB() { - if (sigscale) - delete sigscale; - sigscale = new CProgressBar(); - - if (snrscale) - delete snrscale; - snrscale = new CProgressBar(); - - if (timescale) - delete timescale; + ResetPB(); timescale = new CProgressBar(); timescale->setType(CProgressBar::PB_TIMESCALE); } @@ -248,37 +247,24 @@ void CInfoViewer::changePB() void CInfoViewer::initClock() { - static int gradient_top = g_settings.theme.infobar_gradient_top; - static int gradient_c2c = g_settings.theme.gradient_c2c; - - if ((gradient_top != g_settings.theme.infobar_gradient_top || gradient_c2c != g_settings.theme.gradient_c2c) && clock != NULL) { - gradient_top = g_settings.theme.infobar_gradient_top; - gradient_c2c = g_settings.theme.gradient_c2c; - clock->clearSavedScreen(); - delete clock; - clock = NULL; - } + int gradient_top = g_settings.theme.infobar_gradient_top; + //basic init for clock object if (clock == NULL){ clock = new CComponentsFrmClock(); - clock->setClockBlink("%H.%M"); + clock->setClockFormat("%H:%M", "%H %M"); clock->setClockIntervall(1); - clock->doPaintBg(!gradient_top); - clock->enableTboxSaveScreen(gradient_top); - if (time_width) - clock->setWidth(time_width); } + InfoClock->getInstance()->disableInfoClock(); + clock->enableColBodyGradient(gradient_top, COL_INFOBAR_PLUS_0); + clock->enableSegmentSaveScreen(gradient_top); clock->setColorBody(COL_INFOBAR_PLUS_0); clock->setCorner(RADIUS_LARGE, CORNER_TOP_RIGHT); - clock->setClockFont(SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME); - clock->setClockAlignment(CC_ALIGN_RIGHT | CC_ALIGN_BOTTOM); - clock->refresh(); - + clock->doPaintBg(!gradient_top); + clock->setClockFont(g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]); clock->setPos(BoxEndX - 10 - clock->getWidth(), ChanNameY); clock->setTextColor(COL_INFOBAR_TEXT); - clock->setClockFormat("%H:%M"); - clock->setClockBlink("%H %M"); } void CInfoViewer::showRecordIcon (const bool show) @@ -306,7 +292,7 @@ void CInfoViewer::showRecordIcon (const bool show) int records = crm->GetRecordCount(); - const int radius = RADIUS_MIN; + const int ChanName_X = BoxStartX + ChanWidth + SHADOW_OFFSET; const int icon_space = 3, box_posY = 12; int box_len = 0, rec_icon_posX = 0, ts_icon_posX = 0; @@ -346,8 +332,14 @@ void CInfoViewer::showRecordIcon (const bool show) if (show) { - frameBuffer->paintBoxRel(box_posX + SHADOW_OFFSET, BoxStartY + box_posY + SHADOW_OFFSET, box_len, chanH, COL_INFOBAR_SHADOW_PLUS_0, radius); - frameBuffer->paintBoxRel(box_posX, BoxStartY + box_posY , box_len, chanH, COL_INFOBAR_PLUS_0, radius); + if (rec == NULL){ //TODO: full refactoring of this icon handler + rec = new CComponentsShapeSquare(box_posX, BoxStartY + box_posY , box_len, chanH, NULL, CC_SHADOW_ON, COL_RED, COL_INFOBAR_PLUS_0); + rec->setFrameThickness(2); + rec->setShadowWidth(3); + rec->setCorner(RADIUS_MIN, CORNER_ALL); + } + if (!rec->isPainted()) + rec->paint(CC_SAVE_SCREEN_NO); if (rec_mode != CRecordManager::RECMODE_TSHIFT) g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->RenderString (rec_icon_posX + rec_icon_w + icon_space, BoxStartY + box_posY + chanH, box_len, records_msg, COL_INFOBAR_TEXT); @@ -380,13 +372,11 @@ void CInfoViewer::showRecordIcon (const bool show) void CInfoViewer::paintBackground(int col_NumBox) { - int c_rad_large = RADIUS_LARGE; - int c_shadow_width = (c_rad_large * 2) + 1; int c_rad_mid = RADIUS_MID; int BoxEndInfoY = BoxEndY; if (showButtonBar) // add button bar and blinkenlights BoxEndInfoY += infoViewerBB->InfoHeightY_Info + infoViewerBB->bottom_bar_offset; - // kill left side +#if 0 // kill left side frameBuffer->paintBackgroundBox(BoxStartX, BoxStartY + ChanHeight - 6, BoxStartX + ChanWidth / 3, @@ -402,34 +392,53 @@ void CInfoViewer::paintBackground(int col_NumBox) frameBuffer->paintBox(ChanInfoX + SHADOW_OFFSET, BoxEndInfoY - c_shadow_width, BoxEndX - c_shadow_width, BoxEndInfoY + SHADOW_OFFSET, COL_INFOBAR_SHADOW_PLUS_0, c_rad_large, CORNER_BOTTOM_LEFT); - +#endif // background for channel name/logo and clock paintHead(); // background for epg data - frameBuffer->paintBox(ChanInfoX, ChanNameY + time_height, BoxEndX, BoxEndY, - COL_INFOBAR_PLUS_0, c_rad_large, (showButtonBar ? CORNER_NONE : CORNER_BOTTOM)); + paintBody(); // number box - frameBuffer->paintBoxRel(BoxStartX + SHADOW_OFFSET, BoxStartY + SHADOW_OFFSET, - ChanWidth, ChanHeight, - COL_INFOBAR_SHADOW_PLUS_0, c_rad_mid); - frameBuffer->paintBoxRel(BoxStartX, BoxStartY, - ChanWidth, ChanHeight, - col_NumBox, c_rad_mid); + if (numbox == NULL) //TODO: move into an own member, paintNumBox() or so... + numbox = new CComponentsShapeSquare(BoxStartX, BoxStartY, ChanWidth, ChanHeight, NULL, CC_SHADOW_ON); + else + numbox->setDimensionsAll(BoxStartX, BoxStartY, ChanWidth, ChanHeight); + + numbox->setColorBody(g_settings.theme.infobar_gradient_top ? COL_MENUHEAD_PLUS_0 : col_NumBox); + numbox->enableColBodyGradient(g_settings.theme.infobar_gradient_top, g_settings.theme.infobar_gradient_top ? COL_INFOBAR_PLUS_0 : col_NumBox, g_settings.theme.infobar_gradient_top_direction); + numbox->setCorner(c_rad_mid, CORNER_ALL); + numbox->paint(CC_SAVE_SCREEN_NO); } void CInfoViewer::paintHead() { - CComponentsShapeSquare header(ChanInfoX, ChanNameY, BoxEndX-ChanInfoX, time_height); + if (header == NULL){ + header = new CComponentsShapeSquare(ChanInfoX, ChanNameY, BoxEndX-ChanInfoX, time_height, NULL, CC_SHADOW_RIGHT); + header->setCorner(RADIUS_LARGE, CORNER_TOP_RIGHT); + }else + header->setDimensionsAll(ChanInfoX, ChanNameY, BoxEndX-ChanInfoX, time_height); - header.setColorBody(g_settings.theme.infobar_gradient_top ? COL_MENUHEAD_PLUS_0 : COL_INFOBAR_PLUS_0); - header.enableColBodyGradient(g_settings.theme.infobar_gradient_top); - header.set2ndColor(COL_INFOBAR_PLUS_0); - header.setCorner(RADIUS_LARGE, CORNER_TOP_RIGHT); - clock->setColorBody(header.getColorBody()); + header->setColorBody(g_settings.theme.infobar_gradient_top ? COL_MENUHEAD_PLUS_0 : COL_INFOBAR_PLUS_0); + header->enableColBodyGradient(g_settings.theme.infobar_gradient_top, COL_INFOBAR_PLUS_0, g_settings.theme.infobar_gradient_top_direction); + clock->setColorBody(header->getColorBody()); - header.paint(CC_SAVE_SCREEN_NO); + header->paint(CC_SAVE_SCREEN_NO); + header_height = header->getHeight(); +} + +void CInfoViewer::paintBody() +{ + int h_body = InfoHeightY - header_height + (g_settings.infobar_casystem_display < 2 ? infoViewerBB->bottom_bar_offset : 0); + if (body == NULL) + body = new CComponentsShapeSquare(ChanInfoX, ChanNameY + header_height, BoxEndX-ChanInfoX, h_body, NULL, CC_SHADOW_RIGHT); + else + body->setDimensionsAll(ChanInfoX, ChanNameY + header_height, BoxEndX-ChanInfoX, h_body); + + body->setColorBody(g_settings.theme.infobar_gradient_body ? COL_MENUHEAD_PLUS_0 : COL_INFOBAR_PLUS_0); + body->enableColBodyGradient(g_settings.theme.infobar_gradient_body, COL_INFOBAR_PLUS_0, g_settings.theme.infobar_gradient_body_direction); + + body->paint(CC_SAVE_SCREEN_NO); } void CInfoViewer::show_current_next(bool new_chan, int epgpos) @@ -513,7 +522,6 @@ void CInfoViewer::showMovieTitle(const int playState, const t_channel_id &Channe aspectRatio = 0; last_curr_id = last_next_id = 0; showButtonBar = true; - fileplay = true; reset_allScala(); if (!gotTime) @@ -550,7 +558,7 @@ void CInfoViewer::showMovieTitle(const int playState, const t_channel_id &Channe if (g_settings.infobar_show_channellogo > 1) ChannelLogoMode = showChannelLogo(current_channel_id, 0); if (ChannelLogoMode == 0 || ChannelLogoMode == 3 || ChannelLogoMode == 4) - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->RenderString(ChanNameX + 10 , ChanNameY + time_height,BoxEndX - (ChanNameX + 20) - time_width - LEFT_OFFSET - 10 ,ChannelName, COL_INFOBAR_TEXT); + g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->RenderString(ChanNameX + 10 , ChanNameY + header_height,BoxEndX - (ChanNameX + 20) - time_width - LEFT_OFFSET - 10 ,ChannelName, COL_INFOBAR_TEXT); // show_Data if (CMoviePlayerGui::getInstance().file_prozent > 100) @@ -559,7 +567,7 @@ void CInfoViewer::showMovieTitle(const int playState, const t_channel_id &Channe const char *unit_short_minute = g_Locale->getText(LOCALE_UNIT_SHORT_MINUTE); char runningRest[32]; // %d can be 10 digits max... snprintf(runningRest, sizeof(runningRest), "%d / %d %s", (curr_pos + 30000) / 60000, (duration - curr_pos + 30000) / 60000, unit_short_minute); - display_Info(g_file_epg.c_str(), g_file_epg1.c_str(), true, false, CMoviePlayerGui::getInstance().file_prozent, NULL, runningRest); + display_Info(g_file_epg.c_str(), g_file_epg1.c_str(), false, CMoviePlayerGui::getInstance().file_prozent, NULL, runningRest); int speed = CMoviePlayerGui::getInstance().GetSpeed(); const char *playicon = NULL; @@ -593,17 +601,14 @@ void CInfoViewer::showMovieTitle(const int playState, const t_channel_id &Channe playicon = NEUTRINO_ICON_BUTTON_HELP; break; } - int icon_w = 0,icon_h = 0; frameBuffer->getIconSize(playicon, &icon_w, &icon_h); - int speedw = 0; if (speed) { sprintf(runningRest, "%dx", speed); speedw = 5 + g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getRenderWidth(runningRest); icon_w += speedw; } - int icon_x = BoxStartX + ChanWidth / 2 - icon_w / 2; int icon_y = BoxStartY + ChanHeight / 2 - icon_h / 2; if (speed) { @@ -613,10 +618,8 @@ void CInfoViewer::showMovieTitle(const int playState, const t_channel_id &Channe icon_x += speedw; } frameBuffer->paintIcon(playicon, icon_x, icon_y); - showLcdPercentOver (); showInfoFile(); - //loop(fadeValue, show_dot , fadeIn); loop(show_dot); aspectRatio = 0; @@ -626,19 +629,17 @@ void CInfoViewer::showMovieTitle(const int playState, const t_channel_id &Channe void CInfoViewer::reset_allScala() { - sigscale->reset(); - snrscale->reset(); - timescale->reset(); + changePB(); lastsig = lastsnr = -1; infoViewerBB->reset_allScala(); } void CInfoViewer::check_channellogo_ca_SettingsChange() { - if (casysChange != g_settings.casystem_display || channellogoChange != g_settings.infobar_show_channellogo) { - casysChange = g_settings.casystem_display; + if (casysChange != g_settings.infobar_casystem_display || channellogoChange != g_settings.infobar_show_channellogo) { + casysChange = g_settings.infobar_casystem_display; channellogoChange = g_settings.infobar_show_channellogo; - infoViewerBB->setBBOffset(); + infoViewerBB->initBBOffset(); start(); } } @@ -779,7 +780,7 @@ void CInfoViewer::showTitle(CZapitChannel * channel, const bool calledFromNumZap { ChanNumWidth = 5 + g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->getRenderWidth (strChanNum); g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->RenderString( - ChanNameX + 5, ChanNameY + time_height, + ChanNameX + 5, ChanNameY + header_height, ChanNumWidth, strChanNum, col_NumBoxText); } } @@ -790,7 +791,7 @@ void CInfoViewer::showTitle(CZapitChannel * channel, const bool calledFromNumZap //fb_pixel_t color = CNeutrinoApp::getInstance ()->channelList->SameTP(new_channel_id) ? COL_INFOBAR_TEXT : COL_INFOBAR_SHADOW_TEXT; fb_pixel_t color = COL_INFOBAR_TEXT; g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->RenderString( - ChanNameX + 10 + ChanNumWidth, ChanNameY + time_height, + ChanNameX + 10 + ChanNumWidth, ChanNameY + header_height, BoxEndX - (ChanNameX + 20) - time_width - LEFT_OFFSET - 10 - ChanNumWidth, ChannelName, color /*COL_INFOBAR_TEXT*/); //provider name @@ -804,7 +805,7 @@ void CInfoViewer::showTitle(CZapitChannel * channel, const bool calledFromNumZap chann_size = 1; chname_width += (chname_width/chann_size/2); - int tmpY = ((ChanNameY + time_height) - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->getDigitOffset() + int tmpY = ((ChanNameY + header_height) - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->getDigitOffset() + g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getDigitOffset()); g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->RenderString( ChanNameX + 10 + ChanNumWidth + chname_width, tmpY, @@ -826,7 +827,7 @@ void CInfoViewer::showTitle(CZapitChannel * channel, const bool calledFromNumZap current = next; next = ""; } - display_Info(current, next, true, false, 0, NULL, NULL, NULL, NULL, true, true); + display_Info(current, next, false, 0, NULL, NULL, NULL, NULL, true, true); } #endif } else { @@ -1306,7 +1307,7 @@ int CInfoViewer::handleMsg (const neutrino_msg_t msg, neutrino_msg_data_t data) } else if ((msg == NeutrinoMessages::EVT_ZAP_COMPLETE) || (msg == NeutrinoMessages::EVT_ZAP_ISNVOD)) { current_channel_id = (*(t_channel_id *)data); - killInfobarText(); + //killInfobarText(); return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_ZAP_CA_ID) { //chanready = 1; @@ -1331,7 +1332,7 @@ int CInfoViewer::handleMsg (const neutrino_msg_t msg, neutrino_msg_data_t data) int curr_pos = CMoviePlayerGui::getInstance().GetPosition(); int duration = CMoviePlayerGui::getInstance().GetDuration(); snprintf(runningRest, sizeof(runningRest), "%d / %d %s", (curr_pos + 30000) / 60000, (duration - curr_pos + 30000) / 60000, unit_short_minute); - display_Info(NULL, NULL, true, false, CMoviePlayerGui::getInstance().file_prozent, NULL, runningRest); + display_Info(NULL, NULL, false, CMoviePlayerGui::getInstance().file_prozent, NULL, runningRest); } else if (!IS_WEBTV(current_channel_id)) { show_Data( true ); } @@ -1402,7 +1403,7 @@ int CInfoViewer::handleMsg (const neutrino_msg_t msg, neutrino_msg_data_t data) showSNR (); return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_MODECHANGED) { - aspectRatio = data; + aspectRatio = (int8_t)data; if (is_visible && showButtonBar) infoViewerBB->showIcon_16_9 (); return messages_return::handled; @@ -1481,7 +1482,7 @@ void CInfoViewer::showSNR () TODO: decouple this */ if (!fileplay && !IS_WEBTV(current_channel_id) && ( g_settings.infobar_show_channellogo == 3 || g_settings.infobar_show_channellogo == 5 || g_settings.infobar_show_channellogo == 6 )) { int chanH = g_SignalFont->getHeight(); - int freqStartY = BoxStartY + 2 * chanH - 3; +// int freqStartY = BoxStartY + 2 * chanH - 3; if ((newfreq && chanready) || SDT_freq_update) { char freq[20]; newfreq = false; @@ -1498,73 +1499,38 @@ void CInfoViewer::showSNR () g_SignalFont->RenderString (3 + BoxStartX + ((ChanWidth - satNameWidth) / 2), BoxStartY + 2 * chanH - 3, satNameWidth, freq, SDT_freq_update ? COL_COLORED_EVENTS_TEXT:COL_INFOBAR_TEXT); SDT_freq_update = false; } - - char percent[10]; - uint16_t ssig, ssnr; - int sw, snr, sig, posx, posy; - - int height; - ssig = CFEManager::getInstance()->getLiveFE()->getSignalStrength(); - ssnr = CFEManager::getInstance()->getLiveFE()->getSignalNoiseRatio(); - - sig = (ssig & 0xFFFF) * 100 / 65535; - snr = (ssnr & 0xFFFF) * 100 / 65535; - height = g_SignalFont->getHeight () - 1; - - if (lastsig != sig) { - lastsig = sig; - posx = BoxStartX + (ChanWidth - (bar_width + 2 + (g_SignalFont->getWidth() * 4))) / 2; - posy = freqStartY; - sigscale->setDimensionsAll(posx, posy+4, bar_width, 10 * g_settings.screen_yres / 100); - sigscale->setColorBody(COL_INFOBAR_PLUS_0); - sigscale->setValues(sig, 100); - sigscale->paint(); - snprintf (percent, sizeof(percent), "%d%%S", sig); - posx = posx + bar_width + 2; - sw = BoxStartX + ChanWidth - posx; - frameBuffer->paintBoxRel (posx, posy, sw, height, COL_INFOBAR_PLUS_0); - g_SignalFont->RenderString (posx, posy + height, sw, percent, COL_INFOBAR_TEXT); - } - if (lastsnr != snr) { - lastsnr = snr; - posx = BoxStartX + (ChanWidth - (bar_width + 2 + (g_SignalFont->getWidth() * 4))) / 2; - posy = freqStartY + height - (2 * g_settings.screen_yres / 100); - snrscale->setDimensionsAll(posx, posy+4, bar_width, 10 * g_settings.screen_yres / 100); - snrscale->setColorBody(COL_INFOBAR_PLUS_0); - snrscale->setValues(snr, 100); - snrscale->paint(); - snprintf (percent, sizeof(percent), "%d%%Q", snr); - posx = posx + bar_width + 2; - sw = BoxStartX + ChanWidth - posx -4; - frameBuffer->paintBoxRel (posx, posy, sw, height-2, COL_INFOBAR_PLUS_0); - g_SignalFont->RenderString (posx, posy + height, sw, percent, COL_INFOBAR_TEXT); + if (sigbox == NULL){ + sigbox = new CSignalBox(BoxStartX+4, BoxStartY+ChanHeight/2-4, ChanWidth-8, ChanHeight/2+2, CFEManager::getInstance()->getLiveFE()); + sigbox->setTextColor(COL_INFOBAR_TEXT); + sigbox->doPaintBg(false); } + sigbox->paint(CC_SAVE_SCREEN_NO); } if(showButtonBar) infoViewerBB->showSysfsHdd(); } void CInfoViewer::display_Info(const char *current, const char *next, - bool UTF8, bool starttimes, const int pb_pos, + bool starttimes, const int pb_pos, const char *runningStart, const char *runningRest, const char *nextStart, const char *nextDuration, bool update_current, bool update_next) { /* dimensions of the two-line current-next "box": - top of box == ChanNameY + time_height (bottom of channel name) + top of box == ChanNameY + header_height (bottom of channel name) bottom of box == BoxEndY - height of box == BoxEndY - (ChanNameY + time_height) + height of box == BoxEndY - (ChanNameY + header_height) middle of box == top + height / 2 - == ChanNameY + time_height + (BoxEndY - (ChanNameY + time_height))/2 - == ChanNameY + time_height + (BoxEndY - ChanNameY - time_height)/2 - == ChanNameY / 2 + time_height / 2 + BoxEndY / 2 - == (BoxEndY + ChanNameY + time_height)/2 + == ChanNameY + header_height + (BoxEndY - (ChanNameY + header_height))/2 + == ChanNameY + header_height + (BoxEndY - ChanNameY - header_height)/2 + == ChanNameY / 2 + header_height / 2 + BoxEndY / 2 + == (BoxEndY + ChanNameY + header_height)/2 The bottom of current info and the top of next info is == middle of box. */ int height = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getHeight(); - int CurrInfoY = (BoxEndY + ChanNameY + time_height) / 2; - int NextInfoY = CurrInfoY + height; // lower end of next info box + int CurrInfoY = (BoxEndY + ChanNameY + header_height) / 2; + int NextInfoY = CurrInfoY/* + height*/; // lower end of next info box int InfoX = ChanInfoX + 10; int xStart = InfoX; @@ -1593,18 +1559,16 @@ void CInfoViewer::display_Info(const char *current, const char *next, int pb_startx = BoxEndX - pb_w - SHADOW_OFFSET; int pb_starty = ChanNameY - (pb_h + 10); int pb_shadow = COL_INFOBAR_SHADOW_PLUS_0; - timescale->setShadowOnOff(true); + timescale->enableShadow(!g_settings.infobar_progressbar); int pb_color = (g_settings.progressbar_design == CProgressBar::PB_MONO) ? COL_INFOBAR_PLUS_0 : COL_INFOBAR_SHADOW_PLUS_0; if(g_settings.infobar_progressbar){ pb_startx = xStart; pb_w = BoxEndX - 10 - xStart; pb_shadow = 0; - timescale->setShadowOnOff(false); } - int tmpY = CurrInfoY - height - ChanNameY + time_height - - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->getDigitOffset()/3; - switch(g_settings.infobar_progressbar) //set progressbar position - { + int tmpY = CurrInfoY - height - ChanNameY + header_height - + g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->getDigitOffset()/3+SHADOW_OFFSET; + switch(g_settings.infobar_progressbar){ //set progressbar position case SNeutrinoSettings::INFOBAR_PROGRESSBAR_ARRANGEMENT_BELOW_CH_NAME: pb_h = (pb_h/3); pb_starty = ChanNameY + (tmpY-pb_h)/2; @@ -1628,52 +1592,82 @@ void CInfoViewer::display_Info(const char *current, const char *next, timescale->setDimensionsAll(pb_startx, pb_starty, pb_w, pb_h); timescale->setColorAll(pb_color, pb_color, pb_shadow); timescale->setValues(pb_p, pb_w); - timescale->paint(); + //printf("paintProgressBar(%d, %d, %d, %d)\n", BoxEndX - pb_w - SHADOW_OFFSET, ChanNameY - (pb_h + 10) , pb_w, pb_h); } int currTimeW = 0; int nextTimeW = 0; - if (runningRest != NULL) - currTimeW = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getRenderWidth(runningRest, UTF8); - if (nextDuration != NULL) - nextTimeW = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getRenderWidth(nextDuration, UTF8); + if (runningRest) + currTimeW = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getRenderWidth(runningRest)+10; + if (nextDuration) + nextTimeW = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->getRenderWidth(nextDuration)+10; int currTimeX = BoxEndX - currTimeW - 10; int nextTimeX = BoxEndX - nextTimeW - 10; - static int oldCurrTimeX = currTimeX; // remember the last pos. of remaining time, in case we change from 20/100min to 21/99min //colored_events init bool colored_event_C = (g_settings.theme.colored_events_infobar == 1); bool colored_event_N = (g_settings.theme.colored_events_infobar == 2); - if (current != NULL && update_current) - { - frameBuffer->paintBox(InfoX, CurrInfoY - height, currTimeX, CurrInfoY, COL_INFOBAR_PLUS_0); - if (runningStart != NULL) - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->RenderString(InfoX, CurrInfoY, info_time_width, runningStart, colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT, 0, UTF8); - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->RenderString(xStart, CurrInfoY, currTimeX - xStart - 5, current, colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT, 0, UTF8); - oldCurrTimeX = currTimeX; - } - - if (currTimeX < oldCurrTimeX) - oldCurrTimeX = currTimeX; - frameBuffer->paintBox(oldCurrTimeX, CurrInfoY-height, BoxEndX, CurrInfoY, COL_INFOBAR_PLUS_0); - oldCurrTimeX = currTimeX; - if (currTimeW != 0) - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->RenderString(currTimeX, CurrInfoY, currTimeW, runningRest, colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT, 0, UTF8); - - if (next != NULL && update_next) - { - frameBuffer->paintBox(InfoX, NextInfoY-height, BoxEndX, NextInfoY, COL_INFOBAR_PLUS_0); - if (nextStart != NULL) - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->RenderString(InfoX, NextInfoY, info_time_width, nextStart, colored_event_N ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT, 0, UTF8); - if (starttimes) - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->RenderString(xStart, NextInfoY, nextTimeX - xStart - 5, next, colored_event_N ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT, 0, UTF8); + //current event + if (current && update_current){ + if (txt_cur_event == NULL) + txt_cur_event = new CComponentsTextTransp(NULL, xStart, CurrInfoY - height, currTimeX - xStart - 5, height); else - g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->RenderString(xStart, NextInfoY, nextTimeX - xStart - 5, next, colored_event_N ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT, 0, UTF8); - if (nextTimeW != 0) - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]->RenderString(nextTimeX, NextInfoY, nextTimeW, nextDuration, colored_event_N ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT, 0, UTF8); + txt_cur_event->setDimensionsAll(xStart, CurrInfoY - height, currTimeX - xStart - 5, height); + txt_cur_event->setText(current, CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO], colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT); + txt_cur_event->paint(CC_SAVE_SCREEN_NO); + if (runningStart){ + if (txt_cur_start == NULL) + txt_cur_start = new CComponentsTextTransp(NULL, InfoX, CurrInfoY - height, info_time_width, height); + else + txt_cur_start->setDimensionsAll(InfoX, CurrInfoY - height, info_time_width, height); + txt_cur_start->setText(runningStart, CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO], colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT); + txt_cur_start->paint(CC_SAVE_SCREEN_NO); + } + + if (runningRest){ + if (txt_cur_event_rest == NULL) + txt_cur_event_rest = new CComponentsTextTransp(NULL, currTimeX, CurrInfoY - height, currTimeW, height); + else + txt_cur_event_rest->setDimensionsAll(currTimeX, CurrInfoY - height, currTimeW, height); + txt_cur_event_rest->setText(runningRest, CTextBox::RIGHT, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO], colored_event_C ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT); + txt_cur_event_rest->paint(CC_SAVE_SCREEN_NO); + } } + + //next event + if (next && update_next) + { + if (txt_next_event == NULL) + txt_next_event = new CComponentsTextTransp(NULL, xStart, NextInfoY, nextTimeX - xStart - 5, height); + else + txt_next_event->setDimensionsAll(xStart, NextInfoY, nextTimeX - xStart - 5, height); + txt_next_event->setText(next, CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO], colored_event_N ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT); + txt_next_event->paint(CC_SAVE_SCREEN_NO); + + if (nextStart){ + if (txt_next_start == NULL) + txt_next_start = new CComponentsTextTransp(NULL, InfoX, NextInfoY, info_time_width, height); + else + txt_next_start->setDimensionsAll(InfoX, NextInfoY, info_time_width, height); + txt_next_start->setText(nextStart, CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO], colored_event_N ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT); + txt_next_start->paint(CC_SAVE_SCREEN_NO); + } + + if (nextDuration){ + if (txt_next_in == NULL) + txt_next_in = new CComponentsTextTransp(NULL, nextTimeX, NextInfoY, nextTimeW, height); + else + txt_next_in->setDimensionsAll(nextTimeX, NextInfoY, nextTimeW, height); + txt_next_in->setText(nextDuration, CTextBox::RIGHT, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO], colored_event_N ? COL_COLORED_EVENTS_TEXT : COL_INFOBAR_TEXT); + txt_next_in->paint(CC_SAVE_SCREEN_NO); + } + } + + //finally paint time scale + if (pb_pos > -1) + timescale->paint(); } void CInfoViewer::show_Data (bool calledFromEvent) @@ -1818,7 +1812,7 @@ void CInfoViewer::show_Data (bool calledFromEvent) else next_upd = false; } - display_Info(current, next, true, true, runningPercent, + display_Info(current, next, true, runningPercent, curr_time, curr_rest, next_time, next_dur, curr_upd, next_upd); #if 0 @@ -1893,7 +1887,7 @@ void CInfoViewer::killInfobarText() { if (infobar_txt){ if (infobar_txt->isPainted()) - infobar_txt->hide(); + infobar_txt->kill(); delete infobar_txt; } infobar_txt = NULL; @@ -1929,7 +1923,8 @@ void CInfoViewer::showInfoFile() infobar_txt = new CComponentsInfoBox(); //get text from file and set it to info object, exit and delete object if failed - if (!infobar_txt->setTextFromFile(infobar_file, CTextBox::CENTER, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO])){ + bool new_text = infobar_txt->setTextFromFile(infobar_file, CTextBox::CENTER, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO]); + if (!new_text){ killInfobarText(); return; } @@ -1937,14 +1932,14 @@ void CInfoViewer::showInfoFile() //set some properties for info object infobar_txt->setDimensionsAll(xStart, yStart, width, height); infobar_txt->setCorner(RADIUS_SMALL); - infobar_txt->setShadowOnOff(true); + infobar_txt->enableShadow(CC_SHADOW_ON, 3); infobar_txt->setTextColor(COL_INFOBAR_TEXT); infobar_txt->setColorBody(COL_INFOBAR_PLUS_0); infobar_txt->doPaintTextBoxBg(false); //paint info, don't save background, if already painted, global hide is also done by killTitle() bool save_bg = !infobar_txt->isPainted(); - if (infobar_txt->textChanged() || virtual_zap_mode) + if (new_text || virtual_zap_mode) infobar_txt->paint(save_bg); } @@ -1958,16 +1953,52 @@ void CInfoViewer::killTitle() int bottom = BoxEndY + SHADOW_OFFSET + infoViewerBB->bottom_bar_offset; if (showButtonBar) bottom += infoViewerBB->InfoHeightY_Info; + if (infoViewerBB->getFooter()) + infoViewerBB->getFooter()->kill(); + if (infoViewerBB->getCABar()) + infoViewerBB->getCABar()->kill(); + if (rec) + rec->kill(); //printf("killTitle(%d, %d, %d, %d)\n", BoxStartX, BoxStartY, BoxEndX+ SHADOW_OFFSET-BoxStartX, bottom-BoxStartY); - frameBuffer->paintBackgroundBox(BoxStartX, BoxStartY, BoxEndX+ SHADOW_OFFSET, bottom); + //frameBuffer->paintBackgroundBox(BoxStartX, BoxStartY, BoxEndX+ SHADOW_OFFSET, bottom); + if (infobar_txt) + infobar_txt->kill(); + numbox->kill(); +#if 0 //not really required to kill sigbox, numbox does this + if (sigbox) + sigbox->kill(); +#endif + header->kill(); +#if 0 //not really required to kill clock, body does this + if (clock) + clock->kill(); +#endif + body->kill(); +#if 0 //not really required to kill epg infos, body does this + if (txt_cur_start) + txt_cur_start->kill(); + if (txt_cur_event) + txt_cur_event->kill(); + if (txt_cur_event_rest) + txt_cur_event_rest->kill(); + if (txt_next_start) + txt_next_start->kill(); + if (txt_next_event) + txt_next_event->kill(); + if (txt_next_in) + txt_next_in->kill(); +#endif + if (timescale) + if (g_settings.infobar_progressbar == SNeutrinoSettings::INFOBAR_PROGRESSBAR_ARRANGEMENT_DEFAULT) + timescale->kill(); if (g_settings.radiotext_enable && g_Radiotext) { g_Radiotext->S_RtOsd = g_Radiotext->haveRadiotext() ? 1 : 0; killRadiotext(); } - killInfobarText(); } showButtonBar = false; + InfoClock->getInstance()->enableInfoClock(); } #if 0 @@ -2031,11 +2062,11 @@ int CInfoViewer::showChannelLogo(const t_channel_id logo_channel_id, const int c else if (g_settings.infobar_show_channellogo == 2 || g_settings.infobar_show_channellogo == 5 || g_settings.infobar_show_channellogo == 6) // paint logo in place of channel name { // check logo dimensions - g_PicViewer->rescaleImageDimensions(&logo_w, &logo_h, chan_w, time_height); + g_PicViewer->rescaleImageDimensions(&logo_w, &logo_h, chan_w, header_height); // hide channel name // this is too ugly... ChannelName = ""; // calculate logo position - y_mid = ChanNameY + time_height / 2; + y_mid = ChanNameY + header_height / 2; logo_x = start_x + 10 + channel_number_width;; logo_y = y_mid - logo_h / 2; if (g_settings.infobar_show_channellogo == 2) @@ -2047,9 +2078,9 @@ int CInfoViewer::showChannelLogo(const t_channel_id logo_channel_id, const int c { // check logo dimensions int Logo_max_width = chan_w - logo_w - 10; - g_PicViewer->rescaleImageDimensions(&logo_w, &logo_h, Logo_max_width, time_height); + g_PicViewer->rescaleImageDimensions(&logo_w, &logo_h, Logo_max_width, header_height); // calculate logo position - y_mid = ChanNameY + time_height / 2; + y_mid = ChanNameY + header_height / 2; logo_x = start_x + 10; logo_y = y_mid - logo_h / 2; // set channel name x pos right of the logo @@ -2145,3 +2176,21 @@ int CInfoViewerHandler::exec (CMenuTarget * parent, const std::string & /*action return res; } #endif + +void CInfoViewer::ResetModules() +{ + delete header; header = NULL; + delete body; body = NULL; + delete infobar_txt; infobar_txt = NULL; + delete clock; clock = NULL; + delete txt_cur_start; txt_cur_start = NULL; + delete txt_cur_event; txt_cur_event = NULL; + delete txt_cur_event_rest; txt_cur_event_rest = NULL; + delete txt_next_start; txt_next_start = NULL; + delete txt_next_event; txt_next_event = NULL; + delete txt_next_in; txt_next_in = NULL; + delete numbox; numbox = NULL; + ResetPB(); + delete rec; rec = NULL; + infoViewerBB->ResetModules(); +} diff --git a/src/gui/infoviewer.h b/src/gui/infoviewer.h index c4283f343..176ce02c5 100644 --- a/src/gui/infoviewer.h +++ b/src/gui/infoviewer.h @@ -52,6 +52,8 @@ class CInfoViewer CFrameBuffer * frameBuffer; CInfoViewerBB* infoViewerBB; CComponentsFrmClock *clock; + CComponentsShapeSquare *header , *numbox, *body, *rec; + CComponentsTextTransp *txt_cur_start, *txt_cur_event, *txt_cur_event_rest, *txt_next_start, *txt_next_event, *txt_next_in; bool gotTime; bool recordModeActive; @@ -90,7 +92,7 @@ class CInfoViewer int time_width; int time_height; int info_time_width; - + int header_height; bool newfreq ; static const short bar_width = 72; static event_id_t last_curr_id, last_next_id; @@ -101,15 +103,18 @@ class CInfoViewer CChannelEventList::iterator eli; int lastsnr, lastsig, lasttime; - CProgressBar *snrscale, *sigscale, *timescale; + CProgressBar *timescale; + CSignalBox *sigbox; + bool casysChange; bool channellogoChange; uint32_t lcdUpdateTimer; void paintBackground(int col_Numbox); void paintHead(); + void paintBody(); void show_Data( bool calledFromEvent = false ); - void display_Info(const char *current, const char *next, bool UTF8 = true, + void display_Info(const char *current, const char *next, bool starttimes = true, const int pb_pos = -1, const char *runningStart = NULL, const char *runningRest = NULL, const char *nextStart = NULL, const char *nextDuration = NULL, @@ -174,12 +179,14 @@ class CInfoViewer int handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data); void clearVirtualZapMode() {virtual_zap_mode = false;} void changePB(); + void ResetPB(); void showSNR(); void Init(void); bool SDT_freq_update; void setUpdateTimer(uint64_t interval); uint32_t getUpdateTimer(void) { return lcdUpdateTimer; } inline t_channel_id get_current_channel_id(void) { return current_channel_id; } + void ResetModules(); }; #if 0 class CInfoViewerHandler : public CMenuTarget diff --git a/src/gui/infoviewer_bb.cpp b/src/gui/infoviewer_bb.cpp index 3760a7530..bd81e93f0 100644 --- a/src/gui/infoviewer_bb.cpp +++ b/src/gui/infoviewer_bb.cpp @@ -89,7 +89,7 @@ CInfoViewerBB::CInfoViewerBB() bbIconInfo[0].h = 0; BBarY = 0; BBarFontY = 0; - + foot = cabar = NULL; Init(); } @@ -109,7 +109,7 @@ void CInfoViewerBB::Init() } InfoHeightY_Info = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight() + 5; - setBBOffset(); + initBBOffset(); changePB(); } @@ -120,10 +120,7 @@ CInfoViewerBB::~CInfoViewerBB() pthread_cancel(scrambledT); scrambledT = 0; } - if (hddscale) - delete hddscale; - if (sysscale) - delete sysscale; + ResetModules(); } CInfoViewerBB* CInfoViewerBB::getInstance() @@ -181,7 +178,7 @@ void CInfoViewerBB::getBBIconInfo() iconView = checkBBIcon(NEUTRINO_ICON_RESOLUTION_1280, &w, &h); break; case CInfoViewerBB::ICON_CA: - if (g_settings.casystem_display == 2) + if (g_settings.infobar_casystem_display == 2) iconView = checkBBIcon(NEUTRINO_ICON_SCRAMBLED2, &w, &h); break; case CInfoViewerBB::ICON_TUNER: @@ -409,7 +406,21 @@ void CInfoViewerBB::showBBButtons(const int modus) } if (paint) { + fb_pixel_t *pixbuf = NULL; + int buf_x = bbIconMinX; + int buf_y = BBarY; + int buf_w = g_InfoViewer->BoxEndX-bbIconMinX; + int buf_h = InfoHeightY_Info; + if (modus != -1) { + pixbuf = new fb_pixel_t[buf_w * buf_h]; +//printf("\nbuf_x: %d, buf_y: %d, buf_w: %d, buf_h: %d, pixbuf: %p\n \n", buf_x, buf_y, buf_w, buf_h, pixbuf); + frameBuffer->SaveScreen(buf_x, buf_y, buf_w, buf_h, pixbuf); + } paintFoot(minX - g_InfoViewer->ChanInfoX); + if ((modus != -1) && (pixbuf != NULL)) { + frameBuffer->RestoreScreen(buf_x, buf_y, buf_w, buf_h, pixbuf); + delete [] pixbuf; + } int last_x = minX; for (i = BUTTON_MAX; i > 0;) { --i; @@ -464,7 +475,7 @@ void CInfoViewerBB::paintshowButtonBar() } g_InfoViewer->sec_timer_id = g_RCInput->addTimer(1*1000*1000, false); - if (g_settings.casystem_display < 2) + if (g_settings.infobar_casystem_display < 2) paintCA_bar(0,0); paintFoot(); @@ -492,15 +503,14 @@ void CInfoViewerBB::paintFoot(int w) { int width = (w == 0) ? g_InfoViewer->BoxEndX - g_InfoViewer->ChanInfoX : w; - CComponentsShapeSquare foot(g_InfoViewer->ChanInfoX, BBarY, width, InfoHeightY_Info); + if (foot == NULL) + foot = new CComponentsShapeSquare(g_InfoViewer->ChanInfoX, BBarY, width, InfoHeightY_Info, NULL, CC_SHADOW_ON); - foot.setColorBody(COL_INFOBAR_BUTTONS_BACKGROUND); - foot.enableColBodyGradient(g_settings.theme.infobar_gradient_bottom); - foot.setColBodyGradient(CColorGradient::gradientDark2Light, CFrameBuffer::gradientVertical); - foot.setCorner(RADIUS_LARGE, CORNER_BOTTOM); - foot.set2ndColor(COL_INFOBAR_PLUS_0); + foot->setColorBody(COL_INFOBAR_BUTTONS_BACKGROUND); + foot->enableColBodyGradient(g_settings.theme.infobar_gradient_bottom, COL_INFOBAR_PLUS_0, g_settings.theme.infobar_gradient_bottom_direction); + foot->setCorner(RADIUS_LARGE, CORNER_BOTTOM); - foot.paint(CC_SAVE_SCREEN_NO); + foot->paint(CC_SAVE_SCREEN_NO); } void CInfoViewerBB::showIcon_SubT() @@ -704,6 +714,7 @@ void CInfoViewerBB::showSysfsHdd() void CInfoViewerBB::showBarSys(int percent) { if (is_visible){ + sysscale->doPaintBg(false); sysscale->setDimensionsAll(bbIconMinX, BBarY + InfoHeightY_Info / 2 - 2 - 6, hddwidth, 6); sysscale->setValues(percent, 100); sysscale->paint(); @@ -713,6 +724,7 @@ void CInfoViewerBB::showBarSys(int percent) void CInfoViewerBB::showBarHdd(int percent) { if (is_visible) { + hddscale->doPaintBg(false); if (percent >= 0){ hddscale->setDimensionsAll(bbIconMinX, BBarY + InfoHeightY_Info / 2 + 2 + 0, hddwidth, 6); hddscale->setValues(percent, 100); @@ -727,8 +739,8 @@ void CInfoViewerBB::showBarHdd(int percent) void CInfoViewerBB::paint_ca_icons(int caid, const char *icon, int &icon_space_offset) { char buf[20]; - int endx = g_InfoViewer->BoxEndX - (g_settings.casystem_frame ? 20 : 10); - int py = g_InfoViewer->BoxEndY + (g_settings.casystem_frame ? 4 : 2); /* hand-crafted, should be automatic */ + int endx = g_InfoViewer->BoxEndX - (g_settings.infobar_casystem_frame ? 20 : 10); + int py = g_InfoViewer->BoxEndY + (g_settings.infobar_casystem_frame ? 4 : 2); /* hand-crafted, should be automatic */ int px = 0; static map > icon_map; const int icon_space = 10, icon_number = 10; @@ -769,7 +781,7 @@ void CInfoViewerBB::paint_ca_icons(int caid, const char *icon, int &icon_space_o if (icon_offset[icon_map[caid].first] == 0) return; - if (g_settings.casystem_display == 0) { + if (g_settings.infobar_casystem_display == 0) { px = endx - (icon_offset[icon_map[caid].first] - icon_space ); } else { icon_space_offset += icon_sizeW[icon_map[caid].first]; @@ -789,10 +801,10 @@ void CInfoViewerBB::paint_ca_icons(int caid, const char *icon, int &icon_space_o void CInfoViewerBB::showIcon_CA_Status(int notfirst) { - if (g_settings.casystem_display == 3) + if (g_settings.infobar_casystem_display == 3) return; if(NeutrinoMessages::mode_ts == CNeutrinoApp::getInstance()->getMode() && !CMoviePlayerGui::getInstance().timeshift){ - if (g_settings.casystem_display == 2) { + if (g_settings.infobar_casystem_display == 2) { fta = true; showOne_CAIcon(); } @@ -805,11 +817,11 @@ void CInfoViewerBB::showIcon_CA_Status(int notfirst) int icon_space_offset = 0; if(!g_InfoViewer->chanready) { - if (g_settings.casystem_display == 2) { + if (g_settings.infobar_casystem_display == 2) { fta = true; showOne_CAIcon(); } - else if(g_settings.casystem_display == 0) { + else if(g_settings.infobar_casystem_display == 0) { for (int i = 0; i < (int)(sizeof(caids)/sizeof(int)); i++) { paint_ca_icons(caids[i], white, icon_space_offset); } @@ -821,7 +833,7 @@ void CInfoViewerBB::showIcon_CA_Status(int notfirst) if(!channel) return; - if (g_settings.casystem_display == 2) { + if (g_settings.infobar_casystem_display == 2) { fta = channel->camap.empty(); showOne_CAIcon(); return; @@ -830,7 +842,7 @@ void CInfoViewerBB::showIcon_CA_Status(int notfirst) if(!notfirst) { #if 0 static int icon_space_offset = 0; - if ((g_settings.casystem_display == 1) && (icon_space_offset)) { + if ((g_settings.infobar_casystem_display == 1) && (icon_space_offset)) { paintCA_bar(0,icon_space_offset); icon_space_offset = 0; } @@ -844,7 +856,7 @@ void CInfoViewerBB::showIcon_CA_Status(int notfirst) if((found = (caid == caids[i]))) break; } - if(g_settings.casystem_display == 0) + if(g_settings.infobar_casystem_display == 0) paint_ca_icons(caids[i], (found ? yellow : white), icon_space_offset); else if(found) paint_ca_icons(caids[i], yellow, icon_space_offset); @@ -854,32 +866,41 @@ void CInfoViewerBB::showIcon_CA_Status(int notfirst) void CInfoViewerBB::paintCA_bar(int left, int right) { - int xcnt = (g_InfoViewer->BoxEndX - g_InfoViewer->ChanInfoX - (g_settings.casystem_frame ? 24 : 0)) / 4; - int ycnt = (bottom_bar_offset - (g_settings.casystem_frame ? 14 : 0)) / 4; + int xcnt = (g_InfoViewer->BoxEndX - g_InfoViewer->ChanInfoX - (g_settings.infobar_casystem_frame ? 24 : 0)) / 4; + int ycnt = (bottom_bar_offset - (g_settings.infobar_casystem_frame ? 14 : 0)) / 4; + int ca_width = g_InfoViewer->BoxEndX - g_InfoViewer->ChanInfoX; if (right) right = xcnt - ((right/4)+1); if (left) left = xcnt - ((left/4)-1); - if (g_settings.casystem_frame) { // with highlighted frame + if (g_settings.infobar_casystem_frame) { // with highlighted frame if (!right || !left) { // paint full bar - // background - frameBuffer->paintBox(g_InfoViewer->ChanInfoX , g_InfoViewer->BoxEndY , g_InfoViewer->BoxEndX , g_InfoViewer->BoxEndY + bottom_bar_offset , COL_INFOBAR_PLUS_0); - // shadow - frameBuffer->paintBox(g_InfoViewer->ChanInfoX + 14, g_InfoViewer->BoxEndY + 4, g_InfoViewer->BoxEndX - 6 , g_InfoViewer->BoxEndY + bottom_bar_offset - 6 , COL_INFOBAR_SHADOW_PLUS_0 , RADIUS_SMALL, CORNER_ALL); - // ca bar - frameBuffer->paintBox(g_InfoViewer->ChanInfoX + 11, g_InfoViewer->BoxEndY + 1, g_InfoViewer->BoxEndX - 11, g_InfoViewer->BoxEndY + bottom_bar_offset - 11, COL_INFOBAR_CASYSTEM_PLUS_0, RADIUS_SMALL, CORNER_ALL); - // highlighed frame - frameBuffer->paintBoxFrame(g_InfoViewer->ChanInfoX + 10, g_InfoViewer->BoxEndY, g_InfoViewer->BoxEndX - g_InfoViewer->ChanInfoX - 2*10, bottom_bar_offset - 10, 1, COL_INFOBAR_CASYSTEM_PLUS_2, RADIUS_SMALL, CORNER_ALL); + // framed ca bar + if (cabar == NULL) + cabar = new CComponentsShapeSquare(g_InfoViewer->ChanInfoX+11, g_InfoViewer->BoxEndY+1, ca_width-22 , bottom_bar_offset-11 , NULL, CC_SHADOW_ON, COL_INFOBAR_CASYSTEM_PLUS_2, COL_INFOBAR_CASYSTEM_PLUS_0); + //cabar->setCorner(RADIUS_SMALL, CORNER_ALL); + cabar->enableShadow(CC_SHADOW_ON, 3); + cabar->setFrameThickness(2); + +// cabar->paint(CC_SAVE_SCREEN_NO); + }else{ //TODO: remove this part, cabar object can do this + if (cabar == NULL) + cabar = new CComponentsShapeSquare(g_InfoViewer->ChanInfoX, g_InfoViewer->BoxEndY, ca_width , bottom_bar_offset-11, NULL, CC_SHADOW_OFF, COL_INFOBAR_CASYSTEM_PLUS_2); + //cabar->setCorner(RADIUS_SMALL, CORNER_ALL); + cabar->disableShadow(); + cabar->setFrameThickness(2); + cabar->setColorBody(COL_INFOBAR_CASYSTEM_PLUS_0); } - else - frameBuffer->paintBox(g_InfoViewer->ChanInfoX + 12 + (right*4), g_InfoViewer->BoxEndY + 2, g_InfoViewer->BoxEndX - 12 - (left*4), g_InfoViewer->BoxEndY + bottom_bar_offset - 12, COL_INFOBAR_CASYSTEM_PLUS_0); + cabar->setFrameThickness(2); + cabar->setCorner(RADIUS_SMALL, CORNER_ALL); + cabar->paint(CC_SAVE_SCREEN_NO); } else - frameBuffer->paintBox(g_InfoViewer->ChanInfoX + (right*4), g_InfoViewer->BoxEndY, g_InfoViewer->BoxEndX - (left*4), g_InfoViewer->BoxEndY + bottom_bar_offset, COL_INFOBAR_CASYSTEM_PLUS_0); - - if (!g_settings.casystem_dotmatrix) //don't show dotmatrix + paintBoxRel(g_InfoViewer->ChanInfoX, g_InfoViewer->BoxEndY, ca_width , bottom_bar_offset, COL_INFOBAR_CASYSTEM_PLUS_0); +#if 1 + if (!g_settings.infobar_casystem_dotmatrix) //don't show dotmatrix return; if (left) @@ -887,9 +908,10 @@ void CInfoViewerBB::paintCA_bar(int left, int right) for (int i = 0 + right; i < xcnt - left; i++) { for (int j = 0; j < ycnt; j++) { - frameBuffer->paintBoxRel((g_InfoViewer->ChanInfoX + (g_settings.casystem_frame ? 14 : 2)) + i*4, g_InfoViewer->BoxEndY + (g_settings.casystem_frame ? 4 : 2) + j*4, 2, 2, COL_INFOBAR_PLUS_1); + frameBuffer->paintBoxRel((g_InfoViewer->ChanInfoX + (g_settings.infobar_casystem_frame ? 14 : 2)) + i*4, g_InfoViewer->BoxEndY + (g_settings.infobar_casystem_frame ? 4 : 2) + j*4, 2, 2, COL_INFOBAR_PLUS_1); } } +#endif } void CInfoViewerBB::changePB() @@ -913,9 +935,25 @@ void CInfoViewerBB::reset_allScala() //lasthdd = lastsys = -1; } -void CInfoViewerBB::setBBOffset() +void CInfoViewerBB::ResetModules() { - bottom_bar_offset = (g_settings.casystem_display < 2) ? (g_settings.casystem_frame ? 36 : 22) : 0; + if (hddscale){ + delete hddscale; hddscale = NULL; + } + if (sysscale){ + delete sysscale; sysscale = NULL; + } + if (foot){ + delete foot; foot = NULL; + } + if (cabar){ + delete cabar; cabar = NULL; + } +} + +void CInfoViewerBB::initBBOffset() +{ + bottom_bar_offset = (g_settings.infobar_casystem_display < 2) ? (g_settings.infobar_casystem_frame ? 36 : 22) : 0; } void* CInfoViewerBB::scrambledThread(void *arg) diff --git a/src/gui/infoviewer_bb.h b/src/gui/infoviewer_bb.h index 03c752eec..360898a21 100644 --- a/src/gui/infoviewer_bb.h +++ b/src/gui/infoviewer_bb.h @@ -108,7 +108,7 @@ class CInfoViewerBB pthread_t scrambledT; CProgressBar *hddscale, *sysscale; - + CComponentsShapeSquare *foot, *cabar; void paintFoot(int w = 0); void showBBIcons(const int modus, const std::string & icon); void getBBIconInfo(void); @@ -148,8 +148,11 @@ class CInfoViewerBB void paintshowButtonBar(); void getBBButtonInfo(void); void reset_allScala(void); - void setBBOffset(void); - + void initBBOffset(void); + // modules + CComponentsShapeSquare* getFooter(void){return foot;} + CComponentsShapeSquare* getCABar(void){return cabar;} + void ResetModules(void); }; #endif // __infoview_bb__ diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index 2b3aa8f64..398ce6fac 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -82,10 +82,7 @@ COsdSetup::COsdSetup(int wizard_mode) mfTtxFontFile = NULL; mfWindowSize = NULL; win_demo = NULL; - - ca_dotmatrix = NULL; - ca_frame = NULL; - + osd_menu_colors = NULL; is_wizard = wizard_mode; width = 40; @@ -98,6 +95,8 @@ COsdSetup::~COsdSetup() delete colorSetupNotifier; delete fontsizenotifier; delete win_demo; + if (osd_menu_colors) + delete osd_menu_colors; } //font settings @@ -253,7 +252,8 @@ int COsdSetup::exec(CMenuTarget* parent, const std::string &actionKey) if (xre != g_settings.screen_xres || yre != g_settings.screen_yres) { printf("[neutrino] new font scale settings x: %d%% y: %d%%\n", g_settings.screen_xres, g_settings.screen_yres); - CNeutrinoApp::getInstance()->SetupFonts(CNeutrinoFonts::FONTSETUP_NEUTRINO_FONT | CNeutrinoFonts::FONTSETUP_NEUTRINO_FONT_INST); + CNeutrinoApp::getInstance()->SetupFonts(CNeutrinoFonts::FONTSETUP_NEUTRINO_FONT | CNeutrinoFonts::FONTSETUP_NEUTRINO_FONT_INST | CNeutrinoFonts::FONTSETUP_DYN_FONT); + CNeutrinoApp::getInstance()->channelList->ResetModules(); //force re init of all modules } return res; } @@ -464,6 +464,25 @@ const CMenuOptionChooser::keyval OPTIONS_COLORED_EVENTS_OPTIONS[OPTIONS_COLORED_ { 2, LOCALE_MISCSETTINGS_COLORED_EVENTS_2 }, //next }; +#define OPTIONS_COL_GRADIENT_OPTIONS_COUNT CC_COLGRAD_TYPES //TODO: add modes for intensity +const CMenuOptionChooser::keyval OPTIONS_COL_GRADIENT_OPTIONS[OPTIONS_COL_GRADIENT_OPTIONS_COUNT] = +{ + { CC_COLGRAD_OFF , LOCALE_OPTIONS_OFF }, + { CC_COLGRAD_COL_A_2_COL_B , LOCALE_COLOR_GRADIENT_A2B }, //color A to color B + { CC_COLGRAD_COL_B_2_COL_A , LOCALE_COLOR_GRADIENT_B2A }, //color B to color A + { CC_COLGRAD_LIGHT_2_DARK , LOCALE_COLOR_GRADIENT_L2D }, //light to dark + { CC_COLGRAD_DARK_2_LIGHT , LOCALE_COLOR_GRADIENT_D2L }, //dark to light + { CC_COLGRAD_COL_LIGHT_DARK_LIGHT , LOCALE_COLOR_GRADIENT_LDL }, //light dark light + { CC_COLGRAD_COL_DARK_LIGHT_DARK , LOCALE_COLOR_GRADIENT_DLD }, //dark light dark +}; + +#define OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS_COUNT 2 +const CMenuOptionChooser::keyval OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS[OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS_COUNT] = +{ + { CFrameBuffer::gradientHorizontal , LOCALE_COLOR_GRADIENT_MODE_DIRECTION_HOR }, //horizontal + { CFrameBuffer::gradientVertical , LOCALE_COLOR_GRADIENT_MODE_DIRECTION_VER }, //vertical +}; + /* these are more descriptive... */ #define _LOCALE_PROGRESSBAR_COLOR_MATRIX LOCALE_MISCSETTINGS_PROGRESSBAR_DESIGN_0 #define _LOCALE_PROGRESSBAR_COLOR_VERTICAL LOCALE_MISCSETTINGS_PROGRESSBAR_DESIGN_1 @@ -492,14 +511,15 @@ int COsdSetup::showOsdSetup() osd_menu->setWizardMode(is_wizard); //menu colors - CMenuWidget osd_menu_colors(LOCALE_MAINMENU_SETTINGS, NEUTRINO_ICON_COLORS, width, MN_WIDGET_ID_OSDSETUP_MENUCOLORS); + if (osd_menu_colors == NULL) + osd_menu_colors = new CMenuWidget(LOCALE_MAINMENU_SETTINGS, NEUTRINO_ICON_COLORS, width, MN_WIDGET_ID_OSDSETUP_MENUCOLORS); //intro with subhead and back button osd_menu->addIntroItems(LOCALE_MAINSETTINGS_OSD); //item menu colors - showOsdMenueColorSetup(&osd_menu_colors); - CMenuForwarder * mf = new CMenuForwarder(LOCALE_COLORMENU_MENUCOLORS, true, NULL, &osd_menu_colors, NULL, CRCInput::RC_red); + showOsdMenueColorSetup(osd_menu_colors); + CMenuForwarder * mf = new CMenuForwarder(LOCALE_COLORMENU_MENUCOLORS, true, NULL, osd_menu_colors, NULL, CRCInput::RC_red); mf->setHint("", LOCALE_MENU_HINT_COLORS); osd_menu->addItem(mf); @@ -592,8 +612,7 @@ int COsdSetup::showOsdSetup() osd_menu->addItem(mc); // round corners - int rounded_corners = g_settings.rounded_corners; - mc = new CMenuOptionChooser(LOCALE_EXTRA_ROUNDED_CORNERS, &rounded_corners, MENU_CORNERSETTINGS_TYPE_OPTIONS, MENU_CORNERSETTINGS_TYPE_OPTION_COUNT, true, this); + mc = new CMenuOptionChooser(LOCALE_EXTRA_ROUNDED_CORNERS, &g_settings.rounded_corners, MENU_CORNERSETTINGS_TYPE_OPTIONS, MENU_CORNERSETTINGS_TYPE_OPTION_COUNT, true, this); mc->setHint("", LOCALE_MENU_HINT_ROUNDED_CORNERS); osd_menu->addItem(mc); @@ -630,7 +649,7 @@ int COsdSetup::showOsdSetup() CVolumeHelper::getInstance()->refresh(); if (oldInfoClockSize != g_settings.infoClockFontSize) { - CInfoClock::getInstance()->setClockFontSize(g_settings.infoClockFontSize); + CInfoClock::getInstance()->setHeight(g_settings.infoClockFontSize); CVolumeHelper::getInstance()->refresh(); if (CNeutrinoApp::getInstance()->isMuted()) { CAudioMute::getInstance()->enableMuteIcon(false); @@ -659,32 +678,34 @@ void COsdSetup::showOsdMenueColorSetup(CMenuWidget *menu_colors) sigc::slot0 slot_repaint = sigc::mem_fun(menu_colors, &CMenuWidget::paint); //we want to repaint after changed Option CColorChooser* chHeadcolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.menu_Head_red, &t.menu_Head_green, &t.menu_Head_blue, - &t.menu_Head_alpha, colorSetupNotifier); + &t.menu_Head_alpha, &g_settings.theme.menu_Head_gradient, colorSetupNotifier); chHeadcolor->setGradient(CColorChooser::gradient_head_body); CColorChooser* chHeadTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.menu_Head_Text_red, &t.menu_Head_Text_green, &t.menu_Head_Text_blue, - NULL, colorSetupNotifier); + NULL, NULL, colorSetupNotifier); chHeadTextcolor->setGradient(CColorChooser::gradient_head_text); CColorChooser* chContentcolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.menu_Content_red, &t.menu_Content_green, &t.menu_Content_blue, - &t.menu_Content_alpha, colorSetupNotifier); + &t.menu_Content_alpha, NULL, colorSetupNotifier); CColorChooser* chContentTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.menu_Content_Text_red, &t.menu_Content_Text_green, &t.menu_Content_Text_blue, - NULL, colorSetupNotifier); + NULL, NULL, colorSetupNotifier); CColorChooser* chContentSelectedcolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.menu_Content_Selected_red, &t.menu_Content_Selected_green, &t.menu_Content_Selected_blue, - &t.menu_Content_Selected_alpha, colorSetupNotifier); + &t.menu_Content_Selected_alpha, NULL, colorSetupNotifier); CColorChooser* chContentSelectedTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.menu_Content_Selected_Text_red, &t.menu_Content_Selected_Text_green, &t.menu_Content_Selected_Text_blue, - NULL, colorSetupNotifier); + NULL, NULL, colorSetupNotifier); CColorChooser* chContentInactivecolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.menu_Content_inactive_red, &t.menu_Content_inactive_green, &t.menu_Content_inactive_blue, - &t.menu_Content_inactive_alpha, colorSetupNotifier); + &t.menu_Content_inactive_alpha, NULL, colorSetupNotifier); CColorChooser* chContentInactiveTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.menu_Content_inactive_Text_red, &t.menu_Content_inactive_Text_green, &t.menu_Content_inactive_Text_blue, - NULL, colorSetupNotifier); + NULL, NULL, colorSetupNotifier); menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_COLORMENUSETUP_MENUHEAD)); CMenuOptionChooser *oj; +#if 0 oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT_C2C, &g_settings.theme.gradient_c2c, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true ); oj->OnAfterChangeOption.connect(slot_repaint); oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT_C2C); menu_colors->addItem(oj); menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE)); +#endif mf = new CMenuDForwarder(LOCALE_COLORMENU_BACKGROUND, true, NULL, chHeadcolor ); mf->setHint("", LOCALE_MENU_HINT_HEAD_BACK); @@ -694,12 +715,18 @@ void COsdSetup::showOsdMenueColorSetup(CMenuWidget *menu_colors) mf->setHint("", LOCALE_MENU_HINT_HEAD_TEXTCOLOR); menu_colors->addItem(mf); - // head color gradient - oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT, &g_settings.theme.menu_Head_gradient, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true ); + // head color gradient //TODO: disable sub options if head gradient is disabled + oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT, &g_settings.theme.menu_Head_gradient, OPTIONS_COL_GRADIENT_OPTIONS, OPTIONS_COL_GRADIENT_OPTIONS_COUNT, true ); oj->OnAfterChangeOption.connect(slot_repaint); oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT); menu_colors->addItem(oj); + // head color gradient direction + oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT_MODE_DIRECTION, &g_settings.theme.menu_Head_gradient_direction, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS_COUNT, true ); + oj->OnAfterChangeOption.connect(slot_repaint); + oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT_DIRECTION); + menu_colors->addItem(oj); + menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_COLORMENUSETUP_MENUCONTENT)); mf = new CMenuDForwarder(LOCALE_COLORMENU_BACKGROUND, true, NULL, chContentcolor ); mf->setHint("", LOCALE_MENU_HINT_CONTENT_BACK); @@ -729,18 +756,31 @@ void COsdSetup::showOsdMenueColorSetup(CMenuWidget *menu_colors) // hintbox color gradient menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_COLORTHEMEMENU_MENU_HINTS)); - oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT, &t.menu_Hint_gradient, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT, &t.menu_Hint_gradient, OPTIONS_COL_GRADIENT_OPTIONS, OPTIONS_COL_GRADIENT_OPTIONS_COUNT, true); oj->OnAfterChangeOption.connect(slot_repaint); oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT); menu_colors->addItem(oj); + // hintbox color gradient direction + oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT_MODE_DIRECTION, &t.menu_Hint_gradient_direction, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS_COUNT, true ); + oj->OnAfterChangeOption.connect(slot_repaint); + oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT_DIRECTION); + menu_colors->addItem(oj); + + // menue separator line gradient enable + menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE)); + oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT_SEPARATOR_ENABLE, &t.menu_Separator_gradient_enable, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true ); + oj->OnAfterChangeOption.connect(slot_repaint); + oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT_SEPARATOR_ENABLE); + menu_colors->addItem(oj); + // infoviewer color CColorChooser* chInfobarcolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.infobar_red, - &t.infobar_green, &t.infobar_blue, &t.infobar_alpha, colorSetupNotifier); + &t.infobar_green, &t.infobar_blue, &t.infobar_alpha, NULL, colorSetupNotifier); CColorChooser* chInfobarTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.infobar_Text_red, - &t.infobar_Text_green, &t.infobar_Text_blue, NULL, colorSetupNotifier); + &t.infobar_Text_green, &t.infobar_Text_blue, NULL, NULL, colorSetupNotifier); CColorChooser* chInfobarCASystem = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.infobar_casystem_red, - &t.infobar_casystem_green, &t.infobar_casystem_blue, &t.infobar_casystem_alpha, colorSetupNotifier); + &t.infobar_casystem_green, &t.infobar_casystem_blue, &t.infobar_casystem_alpha, NULL, colorSetupNotifier); menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_COLORSTATUSBAR_TEXT)); mf = new CMenuDForwarder(LOCALE_COLORMENU_BACKGROUND, true, NULL, chInfobarcolor ); @@ -751,23 +791,48 @@ void COsdSetup::showOsdMenueColorSetup(CMenuWidget *menu_colors) mf->setHint("", LOCALE_MENU_HINT_INFOBAR_TEXTCOLOR); menu_colors->addItem(mf); - mf = new CMenuDForwarder(LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DISPLAY, g_settings.casystem_display < 2, NULL, chInfobarCASystem ); - mf->setHint("", LOCALE_MENU_HINT_INFOBAR_CASYS_COLOR); - menu_colors->addItem(mf); - // infoviewer gradient top - oj = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_GRADIENT_TOP, &t.infobar_gradient_top, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE)); + oj = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_GRADIENT_TOP, &t.infobar_gradient_top, OPTIONS_COL_GRADIENT_OPTIONS, OPTIONS_COL_GRADIENT_OPTIONS_COUNT, true); oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT); menu_colors->addItem(oj); + // infoviewer gradient top direction + oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT_MODE_DIRECTION, &t.infobar_gradient_top_direction, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS_COUNT, true ); + oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT_DIRECTION); + menu_colors->addItem(oj); + + // infoviewer gradient body + menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE)); + oj = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_GRADIENT_BODY, &t.infobar_gradient_body, OPTIONS_COL_GRADIENT_OPTIONS, OPTIONS_COL_GRADIENT_OPTIONS_COUNT, true); + oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT); + menu_colors->addItem(oj); + + // infoviewer gradient body direction + oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT_MODE_DIRECTION, &t.infobar_gradient_body_direction, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS_COUNT, true ); + oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT_DIRECTION); + menu_colors->addItem(oj); + // infoviewer gradient bottom - oj = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_GRADIENT_BOTTOM, &t.infobar_gradient_bottom, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE)); + oj = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_GRADIENT_BOTTOM, &t.infobar_gradient_bottom, OPTIONS_COL_GRADIENT_OPTIONS, OPTIONS_COL_GRADIENT_OPTIONS_COUNT, true); oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT); menu_colors->addItem(oj); + // infoviewer gradient bottom direction + oj = new CMenuOptionChooser(LOCALE_COLOR_GRADIENT_MODE_DIRECTION, &t.infobar_gradient_bottom_direction, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS, OPTIONS_COL_GRADIENT_DIRECTION_OPTIONS_COUNT, true ); + oj->setHint("", LOCALE_MENU_HINT_COLOR_GRADIENT_DIRECTION); + menu_colors->addItem(oj); + + // ca bar + menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE)); + mf = new CMenuDForwarder(LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DISPLAY, g_settings.infobar_casystem_display < 2, NULL, chInfobarCASystem ); + mf->setHint("", LOCALE_MENU_HINT_INFOBAR_CASYS_COLOR); + menu_colors->addItem(mf); + // colored events CColorChooser* chColored_Events = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.colored_events_red, - &t.colored_events_green, &t.colored_events_blue, NULL, colorSetupNotifier); + &t.colored_events_green, &t.colored_events_blue, NULL, NULL, colorSetupNotifier); menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MISCSETTINGS_COLORED_EVENTS)); @@ -891,6 +956,7 @@ void COsdSetup::showOsdFontSizeSetup(CMenuWidget *menu_fonts) fontSettings->addItem(mf); w_index++; } + g_InfoViewer->ResetModules(); } //osd timeouts @@ -967,6 +1033,7 @@ void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) menu_infobar->addIntroItems(LOCALE_MISCSETTINGS_INFOBAR); infobarHddNotifier = new COnOffNotifier(); + sigc::slot0 slot_ibar = sigc::mem_fun(g_InfoViewer, &CInfoViewer::ResetModules); CMenuOptionChooser * mc; CMenuForwarder * mf; @@ -985,6 +1052,7 @@ void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) // display options mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_DISP, &g_settings.infobar_show_channellogo, LOCALE_MISCSETTINGS_INFOBAR_DISP_OPTIONS, LOCALE_MISCSETTINGS_INFOBAR_DISP_OPTIONS_COUNT, true); + mc->OnAfterChangeOption.connect(slot_ibar); mc->setHint("", LOCALE_MENU_HINT_INFOBAR_LOGO); menu_infobar->addItem(mc); @@ -995,25 +1063,32 @@ void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) // satellite/cable provider mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_SAT_DISPLAY, &g_settings.infobar_sat_display, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + mc->OnAfterChangeOption.connect(slot_ibar); mc->setHint("", LOCALE_MENU_HINT_INFOBAR_SAT); menu_infobar->addItem(mc); menu_infobar->addItem(GenericMenuSeparator); // CA system - mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DISPLAY, &g_settings.casystem_display, INFOBAR_CASYSTEM_MODE_OPTIONS, INFOBAR_CASYSTEM_MODE_OPTION_COUNT, true, this); + casystemActivate.Clear(); //ensure empty activator object -> cleanup before add new items, prevents possible segfault! + mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DISPLAY, &g_settings.infobar_casystem_display, INFOBAR_CASYSTEM_MODE_OPTIONS, INFOBAR_CASYSTEM_MODE_OPTION_COUNT, true, this); + mc->OnAfterChangeOption.connect(slot_ibar); mc->setHint("", LOCALE_MENU_HINT_INFOBAR_CASYS); menu_infobar->addItem(mc); - +#if 1 // CA system dotmatrix - ca_dotmatrix = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DOTMATRIX, &g_settings.casystem_dotmatrix, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, g_settings.casystem_display < 2); - ca_dotmatrix->setHint("", LOCALE_MENU_HINT_INFOBAR_CASYS_DOTMATRIX); - menu_infobar->addItem(ca_dotmatrix); - + mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DOTMATRIX, &g_settings.infobar_casystem_dotmatrix, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, g_settings.infobar_casystem_display < 2); + mc->setHint("", LOCALE_MENU_HINT_INFOBAR_CASYS_DOTMATRIX); + menu_infobar->addItem(mc); + casystemActivate.Add(mc); +#endif + // CA system frame - ca_frame = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_FRAME, &g_settings.casystem_frame, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, g_settings.casystem_display < 2); - ca_frame->setHint("", LOCALE_MENU_HINT_INFOBAR_CASYS_FRAME); - menu_infobar->addItem(ca_frame); + mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_FRAME, &g_settings.infobar_casystem_frame, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, g_settings.infobar_casystem_display < 2); + mc->OnAfterChangeOption.connect(slot_ibar); + mc->setHint("", LOCALE_MENU_HINT_INFOBAR_CASYS_FRAME); + menu_infobar->addItem(mc); + casystemActivate.Add(mc); menu_infobar->addItem(GenericMenuSeparator); @@ -1039,6 +1114,7 @@ void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) p_show_tuner_icon = &g_settings.infobar_show_tuner; } mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_SHOW_TUNER, p_show_tuner_icon, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, mc_active); + mc->OnAfterChangeOption.connect(slot_ibar); mc->setHint("", LOCALE_MENU_HINT_INFOBAR_TUNER); menu_infobar->addItem(mc); @@ -1055,6 +1131,7 @@ void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) menu_infobar->addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MISCSETTINGS_PROGRESSBAR)); // progressbar position mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_PROGRESSBAR_INFOBAR_POSITION, &g_settings.infobar_progressbar, PROGRESSBAR_INFOBAR_POSITION_OPTIONS, PROGRESSBAR_INFOBAR_POSITION_COUNT, true); + mc->OnAfterChangeOption.connect(slot_ibar); mc->setHint("", LOCALE_MENU_HINT_PROGRESSBAR_INFOBAR_POSITION); menu_infobar->addItem(mc); } @@ -1177,11 +1254,14 @@ void COsdSetup::showOsdInfoclockSetup(CMenuWidget *menu_infoclock) // digit color CColorChooser* cc = new CColorChooser(LOCALE_COLORMENU_CLOCK_TEXTCOLOR, &g_settings.theme.clock_Digit_red, &g_settings.theme.clock_Digit_green, &g_settings.theme.clock_Digit_blue, - NULL, colorSetupNotifier); + NULL, NULL, colorSetupNotifier); CMenuDForwarder* mf = new CMenuDForwarder(LOCALE_COLORMENU_CLOCK_TEXTCOLOR, !g_settings.infoClockBackground, NULL, cc); mf->setHint("", LOCALE_MENU_HINT_CLOCK_TEXTCOLOR); menu_infoclock->addItem(mf); colorInfoclockNotifier->addItem(mf); + + //ensure clock reinit after setup + CInfoClock::getInstance()->clear(); } bool COsdSetup::changeNotify(const neutrino_locale_t OptionName, void * data) @@ -1198,16 +1278,14 @@ bool COsdSetup::changeNotify(const neutrino_locale_t OptionName, void * data) g_settings.show_menu_hints = * (int*) data; return true; } - else if((ARE_LOCALES_EQUAL(OptionName, LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DISPLAY)) || - (ARE_LOCALES_EQUAL(OptionName, LOCALE_MISCSETTINGS_INFOBAR_SHOW_TUNER))) { + else if((ARE_LOCALES_EQUAL(OptionName, LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DISPLAY)) + ||(ARE_LOCALES_EQUAL(OptionName, LOCALE_MISCSETTINGS_INFOBAR_SHOW_TUNER))) { if (g_InfoViewer == NULL) g_InfoViewer = new CInfoViewer; g_InfoViewer->changePB(); - if (ARE_LOCALES_EQUAL(OptionName, LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DISPLAY)) - { - ca_dotmatrix->setActive(g_settings.casystem_display < 2); - ca_frame->setActive(g_settings.casystem_display < 2); - return true; + if (ARE_LOCALES_EQUAL(OptionName, LOCALE_MISCSETTINGS_INFOBAR_CASYSTEM_DISPLAY)){ + casystemActivate.Activate(g_settings.infobar_casystem_display < 2); + return false; } return false; } @@ -1250,11 +1328,16 @@ bool COsdSetup::changeNotify(const neutrino_locale_t OptionName, void * data) return false; } -int COsdSetup::showContextChanlistMenu() +int COsdSetup::showContextChanlistMenu(CChannelList *parent_channellist) { static int cselected = -1; CMenuWidget * menu_chanlist = new CMenuWidget(LOCALE_MAINMENU_SETTINGS, NEUTRINO_ICON_SETTINGS, width); + + //using native callback to ensure stop header clock in parent channellist before paint this menu window + if (parent_channellist && g_settings.menu_pos == CMenuWidget::MENU_POS_TOP_RIGHT) + menu_chanlist->OnBeforePaint.connect(sigc::mem_fun(parent_channellist->getHeaderObject()->getClockObject(), &CComponentsFrmClock::block)); + menu_chanlist->enableSaveScreen(true); menu_chanlist->enableFade(false); menu_chanlist->setSelected(cselected); @@ -1366,7 +1449,7 @@ void COsdSetup::paintWindowSize(int w, int h) if (win_demo == NULL) { win_demo = new CComponentsShapeSquare(0, 0, 0, 0); win_demo->setFrameThickness(8); - win_demo->setShadowOnOff(CC_SHADOW_OFF); + win_demo->disableShadow(); win_demo->setColorBody(COL_BACKGROUND); win_demo->setColorFrame(COL_RED); win_demo->doPaintBg(true); diff --git a/src/gui/osd_setup.h b/src/gui/osd_setup.h index 6075fdf56..8c29e4f73 100644 --- a/src/gui/osd_setup.h +++ b/src/gui/osd_setup.h @@ -48,7 +48,7 @@ class COsdSetup : public CMenuTarget, public CChangeObserver CColorSetupNotifier *colorSetupNotifier; CFontSizeNotifier *fontsizenotifier; CMenuWidget *osd_menu; - CMenuWidget *submenu_menus; + CMenuWidget *submenu_menus, *osd_menu_colors; CMenuForwarder *mfFontFile, *mfTtxFontFile, *mfWindowSize; char window_size_value[10]; std::string osdFontFile, osdTtxFontFile; @@ -57,9 +57,8 @@ class COsdSetup : public CMenuTarget, public CChangeObserver COnOffNotifier* screensaverNotifier; COnOffNotifier* channellistNotifier; COnOffNotifier* infobarHddNotifier; - CMenuOptionChooser * ca_dotmatrix; - CMenuOptionChooser * ca_frame; - + CGenericMenuActivate casystemActivate; + CGenericMenuActivate gradentHeadDirection, gradentHintDirection, gradentInfobarTopDirection, gradentInfobarBodyDirection, gradentInfobarFootDirection; int width; int is_wizard; int show_menu_hints; @@ -80,7 +79,7 @@ class COsdSetup : public CMenuTarget, public CChangeObserver void paintWindowSize(int w, int h); void AddFontSettingItem(CMenuWidget &font_Settings, const SNeutrinoSettings::FONT_TYPES number_of_fontsize_entry); - + public: enum INFOBAR_CHANNEL_LOGO_POS_OPTIONS { @@ -101,7 +100,7 @@ class COsdSetup : public CMenuTarget, public CChangeObserver ~COsdSetup(); int exec(CMenuTarget* parent, const std::string & actionKey); bool changeNotify(const neutrino_locale_t OptionName, void * /*data*/); - int showContextChanlistMenu(); + int showContextChanlistMenu(CChannelList *parent_channellist = NULL); }; #endif diff --git a/src/gui/themes.cpp b/src/gui/themes.cpp index bef79a397..33dd961ee 100644 --- a/src/gui/themes.cpp +++ b/src/gui/themes.cpp @@ -52,7 +52,7 @@ #define USERDIR "/var" THEMESDIR #define FILE_PREFIX ".theme" - +static SNeutrinoTheme &t = g_settings.theme; CThemes::CThemes() : themefile('\t') { @@ -191,9 +191,9 @@ int CThemes::Show() void CThemes::rememberOldTheme(bool remember) { if ( remember ) { - oldTheme = g_settings.theme; + oldTheme = t; } else { - g_settings.theme = oldTheme; + t = oldTheme; notifier = new CColorSetupNotifier; notifier->changeNotify(NONEXISTANT_LOCALE, NULL); @@ -221,8 +221,11 @@ void CThemes::saveFile(const char *themename) { setTheme(themefile); - if (!themefile.saveConfig(themename)) - printf("[neutrino theme] %s write error\n", themename); + if (themefile.getModifiedFlag()){ + printf("[neutrino theme] save theme into %s\n", themename); + if (!themefile.saveConfig(themename)) + printf("[neutrino theme] %s write error\n", themename); + } } // setup default Colors @@ -234,7 +237,6 @@ void CThemes::setupDefaultColors() void CThemes::setTheme(CConfigFile &configfile) { - SNeutrinoTheme &t = g_settings.theme; configfile.setInt32( "menu_Head_alpha", t.menu_Head_alpha ); configfile.setInt32( "menu_Head_red", t.menu_Head_red ); configfile.setInt32( "menu_Head_green", t.menu_Head_green ); @@ -243,7 +245,11 @@ void CThemes::setTheme(CConfigFile &configfile) configfile.setInt32( "menu_Head_Text_red", t.menu_Head_Text_red ); configfile.setInt32( "menu_Head_Text_green", t.menu_Head_Text_green ); configfile.setInt32( "menu_Head_Text_blue", t.menu_Head_Text_blue ); + configfile.setInt32( "menu_Head_gradient" , t.menu_Head_gradient); + configfile.setInt32( "menu_Head_gradient_direction" , t.menu_Head_gradient_direction); + configfile.setInt32( "menu_Separator_gradient_enable" , t.menu_Separator_gradient_enable); + configfile.setInt32( "menu_Content_alpha", t.menu_Content_alpha ); configfile.setInt32( "menu_Content_red", t.menu_Content_red ); configfile.setInt32( "menu_Content_green", t.menu_Content_green ); @@ -268,7 +274,12 @@ void CThemes::setTheme(CConfigFile &configfile) configfile.setInt32( "menu_Content_inactive_Text_red", t.menu_Content_inactive_Text_red ); configfile.setInt32( "menu_Content_inactive_Text_green", t.menu_Content_inactive_Text_green ); configfile.setInt32( "menu_Content_inactive_Text_blue", t.menu_Content_inactive_Text_blue ); + configfile.setInt32( "menu_Hint_gradient" , t.menu_Hint_gradient); + configfile.setInt32( "menu_Hint_gradient_direction" , t.menu_Hint_gradient_direction); + configfile.setInt32( "menu_ButtonBar_gradient" , t.menu_ButtonBar_gradient); + configfile.setInt32( "menu_ButtonBar_gradient_direction" , t.menu_ButtonBar_gradient_direction); + configfile.setInt32( "infobar_alpha", t.infobar_alpha ); configfile.setInt32( "infobar_red", t.infobar_red ); configfile.setInt32( "infobar_green", t.infobar_green ); @@ -277,12 +288,18 @@ void CThemes::setTheme(CConfigFile &configfile) configfile.setInt32( "infobar_casystem_red", t.infobar_casystem_red ); configfile.setInt32( "infobar_casystem_green", t.infobar_casystem_green ); configfile.setInt32( "infobar_casystem_blue", t.infobar_casystem_blue ); - configfile.setInt32( "infobar_gradient_top", t.infobar_gradient_top ); - configfile.setInt32( "infobar_gradient_bottom", t.infobar_gradient_bottom ); configfile.setInt32( "infobar_Text_alpha", t.infobar_Text_alpha ); configfile.setInt32( "infobar_Text_red", t.infobar_Text_red ); configfile.setInt32( "infobar_Text_green", t.infobar_Text_green ); configfile.setInt32( "infobar_Text_blue", t.infobar_Text_blue ); + + configfile.setInt32( "infobar_gradient_top", t.infobar_gradient_top ); + configfile.setInt32( "infobar_gradient_top_direction", t.infobar_gradient_top_direction ); + configfile.setInt32( "infobar_gradient_body", t.infobar_gradient_body ); + configfile.setInt32( "infobar_gradient_body_direction", t.infobar_gradient_body_direction ); + configfile.setInt32( "infobar_gradient_bottom", t.infobar_gradient_bottom ); + configfile.setInt32( "infobar_gradient_bottom_direction", t.infobar_gradient_bottom_direction ); + configfile.setInt32( "colored_events_alpha", t.colored_events_alpha ); configfile.setInt32( "colored_events_red", t.colored_events_red ); configfile.setInt32( "colored_events_green", t.colored_events_green ); @@ -294,12 +311,10 @@ void CThemes::setTheme(CConfigFile &configfile) configfile.setInt32( "clock_Digit_red", t.clock_Digit_red ); configfile.setInt32( "clock_Digit_green", t.clock_Digit_green ); configfile.setInt32( "clock_Digit_blue", t.clock_Digit_blue ); - configfile.setInt32( "gradient_c2c", t.gradient_c2c ); } void CThemes::getTheme(CConfigFile &configfile) { - SNeutrinoTheme &t = g_settings.theme; t.menu_Head_alpha = configfile.getInt32( "menu_Head_alpha", 0x00 ); t.menu_Head_red = configfile.getInt32( "menu_Head_red", 0x00 ); t.menu_Head_green = configfile.getInt32( "menu_Head_green", 0x0A ); @@ -308,7 +323,11 @@ void CThemes::getTheme(CConfigFile &configfile) t.menu_Head_Text_red = configfile.getInt32( "menu_Head_Text_red", 0x5f ); t.menu_Head_Text_green = configfile.getInt32( "menu_Head_Text_green", 0x46 ); t.menu_Head_Text_blue = configfile.getInt32( "menu_Head_Text_blue", 0x00 ); - t.menu_Head_gradient = configfile.getInt32( "menu_Head_gradient", 1); + + t.menu_Head_gradient = configfile.getInt32( "menu_Head_gradient", CC_COLGRAD_LIGHT_2_DARK); + t.menu_Head_gradient_direction = configfile.getInt32( "menu_Head_gradient_direction", CFrameBuffer::gradientVertical); + t.menu_Separator_gradient_enable = configfile.getInt32( "menu_Separator_gradient_enable", 0); + t.menu_Content_alpha = configfile.getInt32( "menu_Content_alpha", 0x14 ); t.menu_Content_red = configfile.getInt32( "menu_Content_red", 0x00 ); t.menu_Content_green = configfile.getInt32( "menu_Content_green", 0x0f ); @@ -333,32 +352,44 @@ void CThemes::getTheme(CConfigFile &configfile) t.menu_Content_inactive_Text_red = configfile.getInt32( "menu_Content_inactive_Text_red", 55 ); t.menu_Content_inactive_Text_green = configfile.getInt32( "menu_Content_inactive_Text_green", 70 ); t.menu_Content_inactive_Text_blue = configfile.getInt32( "menu_Content_inactive_Text_blue", 85 ); - t.menu_Hint_gradient = configfile.getInt32( "menu_Hint_gradient", 0); + + t.menu_Hint_gradient = configfile.getInt32( "menu_Hint_gradient", CC_COLGRAD_OFF); + t.menu_Hint_gradient_direction = configfile.getInt32( "menu_Hint_gradient_direction", CFrameBuffer::gradientVertical); + t.menu_ButtonBar_gradient = configfile.getInt32( "menu_ButtonBar_gradient", CC_COLGRAD_OFF); + t.menu_ButtonBar_gradient_direction = configfile.getInt32( "menu_ButtonBar_gradient_direction", CFrameBuffer::gradientVertical); + t.infobar_alpha = configfile.getInt32( "infobar_alpha", 0x14 ); t.infobar_red = configfile.getInt32( "infobar_red", 0x00 ); t.infobar_green = configfile.getInt32( "infobar_green", 0x0e ); t.infobar_blue = configfile.getInt32( "infobar_blue", 0x23 ); + + t.infobar_gradient_top = configfile.getInt32( "infobar_gradient_top", CC_COLGRAD_OFF ); + t.infobar_gradient_top_direction = configfile.getInt32( "infobar_gradient_top_direction", CFrameBuffer::gradientVertical ); + t.infobar_gradient_body = configfile.getInt32( "infobar_gradient_body", CC_COLGRAD_OFF); + t.infobar_gradient_body_direction = configfile.getInt32( "infobar_gradient_body_direction", CFrameBuffer::gradientVertical ); + t.infobar_gradient_bottom = configfile.getInt32( "infobar_gradient_bottom", CC_COLGRAD_OFF ); + t.infobar_gradient_bottom_direction = configfile.getInt32( "infobar_gradient_bottom_direction", CFrameBuffer::gradientVertical ); + t.infobar_casystem_alpha = configfile.getInt32( "infobar_casystem_alpha", 0x08 ); t.infobar_casystem_red = configfile.getInt32( "infobar_casystem_red", 0x00 ); t.infobar_casystem_green = configfile.getInt32( "infobar_casystem_green", 0x00 ); t.infobar_casystem_blue = configfile.getInt32( "infobar_casystem_blue", 0x00 ); - t.infobar_gradient_top = configfile.getInt32( "infobar_gradient_top", 0 ); - t.infobar_gradient_bottom = configfile.getInt32( "infobar_gradient_bottom", 0 ); t.infobar_Text_alpha = configfile.getInt32( "infobar_Text_alpha", 0x00 ); t.infobar_Text_red = configfile.getInt32( "infobar_Text_red", 0x64 ); t.infobar_Text_green = configfile.getInt32( "infobar_Text_green", 0x64 ); t.infobar_Text_blue = configfile.getInt32( "infobar_Text_blue", 0x64 ); + t.colored_events_alpha = configfile.getInt32( "colored_events_alpha", 0x00 ); t.colored_events_red = configfile.getInt32( "colored_events_red", 95 ); t.colored_events_green = configfile.getInt32( "colored_events_green", 70 ); t.colored_events_blue = configfile.getInt32( "colored_events_blue", 0 ); t.colored_events_channellist = configfile.getInt32( "colored_events_channellist", 0 ); + t.colored_events_infobar = configfile.getInt32( "colored_events_infobar", 2 ); t.clock_Digit_alpha = configfile.getInt32( "clock_Digit_alpha", t.menu_Content_Text_alpha ); t.clock_Digit_red = configfile.getInt32( "clock_Digit_red", t.menu_Content_Text_red ); t.clock_Digit_green = configfile.getInt32( "clock_Digit_green", t.menu_Content_Text_green ); t.clock_Digit_blue = configfile.getInt32( "clock_Digit_blue", t.menu_Content_Text_blue ); - t.gradient_c2c = configfile.getInt32( "gradient_c2c", 0 ); } void CThemes::move_userDir() diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 905ce3f57..4b087eb27 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -476,9 +476,9 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.infobar_show = configfile.getInt32("infobar_show", configfile.getInt32("infobar_cn", 1)); g_settings.infobar_show_channellogo = configfile.getInt32("infobar_show_channellogo" , 3 ); g_settings.infobar_progressbar = configfile.getInt32("infobar_progressbar" , 1 ); // below channel name - g_settings.casystem_display = configfile.getInt32("casystem_display", 1 );//discreet ca mode default - g_settings.casystem_dotmatrix = configfile.getInt32("casystem_dotmatrix", 1 ); - g_settings.casystem_frame = configfile.getInt32("casystem_frame", 0 ); + g_settings.infobar_casystem_display = configfile.getInt32("infobar_casystem_display", 1 );//discreet ca mode default + g_settings.infobar_casystem_dotmatrix = configfile.getInt32("infobar_casystem_dotmatrix", 0 ); + g_settings.infobar_casystem_frame = configfile.getInt32("infobar_casystem_frame", 1 ); g_settings.scrambled_message = configfile.getBool("scrambled_message", true ); g_settings.volume_pos = configfile.getInt32("volume_pos", CVolumeBar::VOLUMEBAR_POS_TOP_RIGHT ); g_settings.volume_digits = configfile.getBool("volume_digits", true); @@ -549,9 +549,9 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.widget_fade = false; g_settings.widget_fade = configfile.getBool("widget_fade" , false ); + //theme/color options CThemes::getTheme(configfile); - - + g_settings.osd_colorsettings_advanced_mode = configfile.getBool("osd_colorsettings_advanced_mode", false); //personalize g_settings.personalize_pincode = configfile.getString( "personalize_pincode", "0000" ); @@ -1016,9 +1016,9 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32("infobar_show", g_settings.infobar_show); configfile.setInt32("infobar_show_channellogo" , g_settings.infobar_show_channellogo ); configfile.setInt32("infobar_progressbar" , g_settings.infobar_progressbar ); - configfile.setInt32("casystem_display" , g_settings.casystem_display ); - configfile.setInt32("casystem_dotmatrix" , g_settings.casystem_dotmatrix ); - configfile.setInt32("casystem_frame" , g_settings.casystem_frame ); + configfile.setInt32("infobar_casystem_display" , g_settings.infobar_casystem_display ); + configfile.setInt32("infobar_casystem_dotmatrix" , g_settings.infobar_casystem_dotmatrix ); + configfile.setInt32("infobar_casystem_frame" , g_settings.infobar_casystem_frame ); configfile.setBool("scrambled_message" , g_settings.scrambled_message ); configfile.setInt32("volume_pos" , g_settings.volume_pos ); configfile.setBool("volume_digits", g_settings.volume_digits); @@ -1080,9 +1080,9 @@ void CNeutrinoApp::saveSetup(const char * fname) //widget settings configfile.setBool("widget_fade" , g_settings.widget_fade ); + //theme/color options CThemes::setTheme(configfile); - - + configfile.setBool("osd_colorsettings_advanced_mode", g_settings.osd_colorsettings_advanced_mode); //personalize configfile.setString("personalize_pincode", g_settings.personalize_pincode); @@ -2186,6 +2186,7 @@ void CNeutrinoApp::screensaver(bool on) if (on) { m_screensaver = true; + CInfoClock::getInstance()->block(); CScreenSaver::getInstance()->Start(); } else @@ -2205,9 +2206,8 @@ void CNeutrinoApp::RealRun(CMenuWidget &_mainMenu) dprintf(DEBUG_NORMAL, "initialized everything\n"); + //activating infoclock InfoClock = CInfoClock::getInstance(); - if(g_settings.mode_clock) - g_settings.mode_clock = InfoClock->StartClock(); if(g_settings.power_standby || init_cec_setting) standbyMode(true, true); @@ -2525,7 +2525,7 @@ int CNeutrinoApp::showChannelList(const neutrino_msg_t _msg, bool from_menu) channelList_painted = true; neutrino_msg_t msg = _msg; - InfoClock->enableInfoClock(false); + InfoClock->enableInfoClock(false);//TODO: use callback in channel list class StopSubtitles(); //_show: @@ -3819,17 +3819,6 @@ void CNeutrinoApp::switchTvRadioMode(const int prev_mode) } } -//switching clock on or off depends of current displayed or not -void CNeutrinoApp::switchClockOnOff() -{ - if(g_settings.mode_clock) { - InfoClock->enableInfoClock(false); - g_settings.mode_clock = false; - } else { - g_settings.mode_clock = true; - InfoClock->enableInfoClock(true); - } -} /************************************************************************************** * CNeutrinoApp - exec, menuitem callback (shutdown) * @@ -3856,7 +3845,7 @@ int CNeutrinoApp::exec(CMenuTarget* parent, const std::string & actionKey) } else if (actionKey=="clock_switch") { - switchClockOnOff(); + InfoClock->switchClockOnOff(); returnval = menu_return::RETURN_EXIT_ALL; } else if (actionKey=="tv_radio_switch")//used in mainmenu diff --git a/src/system/locals.h b/src/system/locals.h index 2b7c5cfc8..52a6f9a96 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -317,11 +317,23 @@ typedef enum LOCALE_CLOCK_SWITCH_OFF, LOCALE_CLOCK_SWITCH_ON, LOCALE_COLOR_GRADIENT, - LOCALE_COLOR_GRADIENT_C2C, + LOCALE_COLOR_GRADIENT_A2B, + LOCALE_COLOR_GRADIENT_B2A, + LOCALE_COLOR_GRADIENT_D2L, + LOCALE_COLOR_GRADIENT_DLD, + LOCALE_COLOR_GRADIENT_L2D, + LOCALE_COLOR_GRADIENT_LDL, + LOCALE_COLOR_GRADIENT_MODE_DIRECTION, + LOCALE_COLOR_GRADIENT_MODE_DIRECTION_HOR, + LOCALE_COLOR_GRADIENT_MODE_DIRECTION_VER, + LOCALE_COLOR_GRADIENT_SEPARATOR_ENABLE, LOCALE_COLORCHOOSER_ALPHA, LOCALE_COLORCHOOSER_BLUE, LOCALE_COLORCHOOSER_GREEN, LOCALE_COLORCHOOSER_RED, + LOCALE_COLORCHOOSER_SAVE, + LOCALE_COLORMENU_ADVANCED_MODE_OFF, + LOCALE_COLORMENU_ADVANCED_MODE_ON, LOCALE_COLORMENU_BACKGROUND, LOCALE_COLORMENU_CLOCK_TEXTCOLOR, LOCALE_COLORMENU_CONTRAST_FONTS, @@ -1004,7 +1016,8 @@ typedef enum LOCALE_MENU_HINT_CLOCK_SIZE, LOCALE_MENU_HINT_CLOCK_TEXTCOLOR, LOCALE_MENU_HINT_COLOR_GRADIENT, - LOCALE_MENU_HINT_COLOR_GRADIENT_C2C, + LOCALE_MENU_HINT_COLOR_GRADIENT_DIRECTION, + LOCALE_MENU_HINT_COLOR_GRADIENT_SEPARATOR_ENABLE, LOCALE_MENU_HINT_COLORED_EVENTS, LOCALE_MENU_HINT_COLORED_EVENTS_TEXTCOLOR, LOCALE_MENU_HINT_COLORS, @@ -1499,6 +1512,7 @@ typedef enum LOCALE_MISCSETTINGS_INFOBAR_DISP_4, LOCALE_MISCSETTINGS_INFOBAR_DISP_5, LOCALE_MISCSETTINGS_INFOBAR_DISP_6, + LOCALE_MISCSETTINGS_INFOBAR_GRADIENT_BODY, LOCALE_MISCSETTINGS_INFOBAR_GRADIENT_BOTTOM, LOCALE_MISCSETTINGS_INFOBAR_GRADIENT_TOP, LOCALE_MISCSETTINGS_INFOBAR_LOGO_HDD_DIR, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 407159852..0cab6e897 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -317,11 +317,23 @@ const char * locale_real_names[] = "clock_switch_off", "clock_switch_on", "color.gradient", - "color.gradient_c2c", + "color.gradient_a2b", + "color.gradient_b2a", + "color.gradient_d2l", + "color.gradient_dld", + "color.gradient_l2d", + "color.gradient_ldl", + "color.gradient_mode_direction", + "color.gradient_mode_direction_hor", + "color.gradient_mode_direction_ver", + "color.gradient_separator_enable", "colorchooser.alpha", "colorchooser.blue", "colorchooser.green", "colorchooser.red", + "colorchooser.save", + "colormenu.advanced_mode_off", + "colormenu.advanced_mode_on", "colormenu.background", "colormenu.clock_textcolor", "colormenu.contrast_fonts", @@ -1004,7 +1016,8 @@ const char * locale_real_names[] = "menu.hint_clock_size", "menu.hint_clock_textcolor", "menu.hint_color_gradient", - "menu.hint_color_gradient_c2c", + "menu.hint_color_gradient_direction", + "menu.hint_color_gradient_separator_enable", "menu.hint_colored_events", "menu.hint_colored_events_textcolor", "menu.hint_colors", @@ -1499,6 +1512,7 @@ const char * locale_real_names[] = "miscsettings.infobar_disp_4", "miscsettings.infobar_disp_5", "miscsettings.infobar_disp_6", + "miscsettings.infobar_gradient_body", "miscsettings.infobar_gradient_bottom", "miscsettings.infobar_gradient_top", "miscsettings.infobar_logo_hdd_dir", diff --git a/src/system/settings.h b/src/system/settings.h index b108142ca..775a11056 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -61,6 +61,8 @@ struct SNeutrinoTheme unsigned char menu_Head_Text_blue; int menu_Head_gradient; + int menu_Head_gradient_direction; + int menu_Separator_gradient_enable; unsigned char menu_Content_alpha; unsigned char menu_Content_red; @@ -93,6 +95,9 @@ struct SNeutrinoTheme unsigned char menu_Content_inactive_Text_blue; int menu_Hint_gradient; + int menu_Hint_gradient_direction; + int menu_ButtonBar_gradient; + int menu_ButtonBar_gradient_direction; unsigned char infobar_alpha; unsigned char infobar_red; @@ -110,7 +115,11 @@ struct SNeutrinoTheme unsigned char infobar_Text_blue; int infobar_gradient_top; + int infobar_gradient_top_direction; + int infobar_gradient_body; + int infobar_gradient_body_direction; int infobar_gradient_bottom; + int infobar_gradient_bottom_direction; unsigned char colored_events_alpha; unsigned char colored_events_red; @@ -124,7 +133,6 @@ struct SNeutrinoTheme unsigned char clock_Digit_red; unsigned char clock_Digit_green; unsigned char clock_Digit_blue; - int gradient_c2c; }; struct SNeutrinoSettings @@ -171,9 +179,9 @@ struct SNeutrinoSettings int progressbar_timescale_green; int progressbar_timescale_yellow; int progressbar_timescale_invert; - int casystem_display; - int casystem_dotmatrix; - int casystem_frame; + int infobar_casystem_display; + int infobar_casystem_dotmatrix; + int infobar_casystem_frame; int scrambled_message; int volume_pos; int volume_digits; @@ -382,7 +390,9 @@ struct SNeutrinoSettings //widget settings int widget_fade; + //theme/color options SNeutrinoTheme theme; + bool osd_colorsettings_advanced_mode; int contrast_fonts; From 77518102f826e01bad7c2787c26ae38f5312f045 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 19:35:48 +0100 Subject: [PATCH 011/110] CMenuWidget: rework cc modules implementation - don't create header instance on every widget paint. - remove parameters from hide(), not needed anymore - add signal/slot OnBeforePaint(), OnAfterHide() - try to fix infoclock handling - add member ResetModules() - allow separator to paint with gradient --- src/gui/widget/menue.cpp | 141 +++++++++++++++++++++++++-------------- src/gui/widget/menue.h | 12 ++-- 2 files changed, 98 insertions(+), 55 deletions(-) diff --git a/src/gui/widget/menue.cpp b/src/gui/widget/menue.cpp index cea5e336a..c27be79e9 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -547,7 +548,7 @@ CMenuWidget::CMenuWidget() preselected = -1; details_line = NULL; info_box = NULL; - show_details_line = true; + header = NULL; nextShortcut = 1; } @@ -572,10 +573,10 @@ void CMenuWidget::Init(const std::string &Icon, const int mwidth, const mn_widge mglobal = CMenuGlobal::getInstance(); //create CMenuGlobal instance only here frameBuffer = CFrameBuffer::getInstance(); iconfile = Icon; - details_line = new CComponentsDetailLine(); - show_details_line = true; - info_box = new CComponentsInfoBox(); - + details_line = NULL; + + info_box = NULL; + header = NULL; //handle select values if(w_index > MN_WIDGET_ID_MAX){ //error @@ -632,8 +633,26 @@ void CMenuWidget::move(int xoff, int yoff) CMenuWidget::~CMenuWidget() { resetWidget(true); - delete details_line; - delete info_box; + ResetModules(); +} + +void CMenuWidget::ResetModules() +{ + if (header){ + header->hide(); + delete header; + header = NULL; + } + if (details_line){ + details_line->hide(); + delete details_line; + details_line = NULL; + } + if (info_box){ + info_box->kill(); + delete info_box; + info_box = NULL; + } } void CMenuWidget::addItem(CMenuItem* menuItem, const bool defaultselected) @@ -1039,6 +1058,10 @@ void CMenuWidget::hide() if(savescreen && background) restoreScreen();//FIXME else { + if (header) + header->kill(); + if (info_box) + info_box->kill(); frameBuffer->paintBackgroundBoxRel(x, y, full_width, full_height + fbutton_height); //paintHint(-1); } @@ -1050,6 +1073,9 @@ void CMenuWidget::hide() items[count]->init(-1, 0, 0, 0); hint_painted = false; washidden = true; + if (CInfoClock::getInstance()->isRun()) + CInfoClock::getInstance()->enableInfoClock(!CInfoClock::getInstance()->isBlocked()); + OnAfterHide(); } void CMenuWidget::checkHints() @@ -1193,14 +1219,28 @@ void CMenuWidget::initSelectable() void CMenuWidget::paint() { + OnBeforePaint(); + if (header){ + if ((bool)header->getCornerRadius() != (bool)g_settings.rounded_corners) //ensure reset if corner mode was changed + ResetModules(); + } + + if (CInfoClock::getInstance()->isRun()) + CInfoClock::getInstance()->disableInfoClock(); calcSize(); CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8 /*, nameString.c_str()*/); // paint head - CComponentsHeader header(x, y, width + sb_width, hheight, getName(), iconfile); - header.setShadowOnOff(CC_SHADOW_ON); - header.setOffset(10); - header.paint(CC_SAVE_SCREEN_NO); + if (header == NULL){ + header = new CComponentsHeader(x, y, width + sb_width, hheight, getName(), iconfile); + header->enableShadow(CC_SHADOW_RIGHT); + header->setOffset(10); + } + header->setColorBody(COL_MENUHEAD_PLUS_0); + header->setColorShadow(COL_MENUCONTENTDARK_PLUS_0); + header->setCaptionColor(COL_MENUHEAD_TEXT); + header->enableColBodyGradient(g_settings.theme.menu_Head_gradient, COL_MENUCONTENT_PLUS_0); + header->paint(CC_SAVE_SCREEN_NO); // paint body shadow frameBuffer->paintBoxRel(x+SHADOW_OFFSET, y + hheight + SHADOW_OFFSET, width + sb_width, height - hheight + RADIUS_LARGE + (fbutton_count ? fbutton_height : 0), COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); @@ -1220,9 +1260,9 @@ void CMenuWidget::setMenuPos(const int& menu_width) int scr_y = frameBuffer->getScreenY(); int scr_w = frameBuffer->getScreenWidth(); int scr_h = frameBuffer->getScreenHeight(); - int real_h = full_height + fbutton_height + hint_height; - + int x_old = x; + int y_old = y; //configured positions switch(g_settings.menu_pos) { @@ -1254,6 +1294,8 @@ void CMenuWidget::setMenuPos(const int& menu_width) x = /*offx +*/ scr_x + scr_w - menu_width - 10; break; } + if (x_old != x || y_old != y) + ResetModules(); } void CMenuWidget::paintItems() @@ -1364,23 +1406,21 @@ void CMenuWidget::enableSaveScreen(bool enable) void CMenuWidget::paintHint(int pos) { - if (!g_settings.show_menu_hints) + if (!g_settings.show_menu_hints){ + ResetModules(); //ensure clean up on changed setting return; - + } + if (pos < 0 && !hint_painted) return; - info_box->enableGradient(g_settings.theme.menu_Hint_gradient != 0); - info_box->set2ndColor(COL_INFOBAR_SHADOW_PLUS_1); // COL_INFOBAR_SHADOW_PLUS_1 is default footer color - - if (hint_painted) { /* clear detailsline line */ if (details_line) - savescreen ? details_line->hide() : details_line->kill(); + details_line->hide(); /* clear info box */ if ((info_box) && (pos < 0)) - savescreen ? info_box->hide(true) : info_box->kill(); + savescreen ? info_box->hide() : info_box->kill(); hint_painted = false; } if (pos < 0) @@ -1390,7 +1430,7 @@ void CMenuWidget::paintHint(int pos) if (!item->hintIcon && item->hint == NONEXISTANT_LOCALE && item->hintText.empty()) { if (info_box) { - savescreen ? info_box->hide(false) : info_box->kill(); + savescreen ? info_box->hide() : info_box->kill(); hint_painted = false; } return; @@ -1413,35 +1453,38 @@ void CMenuWidget::paintHint(int pos) int imarkh = iheight/2+1; //init details line - if (details_line){ - details_line->setXPos(xpos); - details_line->setYPos(ypos1a); - details_line->setYPosDown(ypos2a); - details_line->setHMarkTop(imarkh); - details_line->setHMarkDown(markh); - details_line->syncSysColors(); - } + if (details_line == NULL) + details_line = new CComponentsDetailLine(); + + details_line->setXPos(xpos); + details_line->setYPos(ypos1a); + details_line->setYPosDown(ypos2a); + details_line->setHMarkTop(imarkh); + details_line->setHMarkDown(markh); + details_line->syncSysColors(); //init infobox std::string str = item->hintText.empty() ? g_Locale->getText(item->hint) : item->hintText; - if (info_box){ - info_box->setDimensionsAll(x, ypos2, iwidth, hint_height); - info_box->setFrameThickness(2); - info_box->removeLineBreaks(str); - info_box->setText(str, CTextBox::AUTO_WIDTH, g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT], COL_MENUCONTENT_TEXT); - info_box->setCorner(RADIUS_LARGE); - info_box->syncSysColors(); - info_box->setColorBody(COL_MENUCONTENTDARK_PLUS_0); - info_box->setShadowOnOff(CC_SHADOW_ON); - info_box->setPicture(item->hintIcon ? item->hintIcon : ""); - } - + if (info_box == NULL) + info_box = new CComponentsInfoBox(); + + info_box->setDimensionsAll(x, ypos2, iwidth, hint_height); + info_box->setFrameThickness(2); + info_box->removeLineBreaks(str); + info_box->setText(str, CTextBox::AUTO_WIDTH, g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT], COL_MENUCONTENT_TEXT); + info_box->setCorner(RADIUS_LARGE); + info_box->setColorAll(COL_MENUCONTENT_PLUS_6, COL_MENUCONTENTDARK_PLUS_0, COL_MENUCONTENTDARK_PLUS_0); + info_box->enableShadow(); + info_box->setPicture(item->hintIcon ? item->hintIcon : ""); + info_box->enableColBodyGradient(g_settings.theme.menu_Hint_gradient, COL_INFOBAR_SHADOW_PLUS_1, g_settings.theme.menu_Hint_gradient_direction);// COL_INFOBAR_SHADOW_PLUS_1 is default footer color + //paint result - if (show_details_line) - details_line->paint(savescreen); - info_box->paint(savescreen); + if (details_line) + details_line->paint(); + if (info_box) + info_box->paint(savescreen); - hint_painted = true; + hint_painted = info_box ? info_box->isPainted() : false; } void CMenuWidget::addKey(neutrino_msg_t key, CMenuTarget *menue, const std::string & action) @@ -1564,7 +1607,7 @@ int CMenuOptionNumberChooser::exec(CMenuTarget*) // give the observer a chance to modify the value paint(true); - + OnAfterChangeOption(); if (wantsRepaint) res = menu_return::RETURN_REPAINT; @@ -2254,8 +2297,8 @@ int CMenuSeparator::paint(bool selected) frameBuffer->paintBoxRel(x,y, dx, height, item_bgcolor); if ((type & LINE)) { - frameBuffer->paintHLineRel(x+10,dx-20,y+(height>>1), COL_MENUCONTENT_PLUS_3); - frameBuffer->paintHLineRel(x+10,dx-20,y+(height>>1)+1, COL_MENUCONTENT_PLUS_1); + int grad = g_settings.theme.menu_Separator_gradient_enable ? CC_COLGRAD_COL_DARK_LIGHT_DARK : CC_COLGRAD_OFF; + paintBoxRel(x+10, y+(height>>1), dx-20, 2, COL_MENUCONTENT_PLUS_3, 0, CORNER_NONE, grad, COL_MENUCONTENT_PLUS_0, CFrameBuffer::gradientHorizontal, CColorGradient::light); } if ((type & STRING)) { diff --git a/src/gui/widget/menue.h b/src/gui/widget/menue.h index 1d55bfbab..97bf7bd26 100644 --- a/src/gui/widget/menue.h +++ b/src/gui/widget/menue.h @@ -308,7 +308,7 @@ class CAbstractMenuOptionChooser : public CMenuItem optionValue = NULL; } ~CAbstractMenuOptionChooser(){} - + sigc::signal OnAfterChangeOption; }; class CMenuOptionNumberChooser : public CAbstractMenuOptionChooser @@ -444,7 +444,7 @@ class CMenuOptionChooser : public CAbstractMenuOptionChooser int getWidth(void); void setOptions(const struct keyval * const Options, const unsigned Number_Of_Options); void setOptions(const struct keyval_ext * const Options, const unsigned Number_Of_Options); - sigc::signal OnAfterChangeOption; + int paint(bool selected); int exec(CMenuTarget* parent); @@ -497,7 +497,7 @@ class CMenuGlobal static CMenuGlobal* getInstance(); }; -class CMenuWidget : public CMenuTarget +class CMenuWidget : public CMenuTarget, public CComponentsSignals { private: mn_widget_id_t widget_index; @@ -505,7 +505,7 @@ class CMenuWidget : public CMenuTarget CComponentsDetailLine *details_line; CComponentsInfoBox *info_box; int hint_height; - bool show_details_line; + CComponentsHeader *header; protected: std::string nameString; neutrino_locale_t name; @@ -562,7 +562,7 @@ class CMenuWidget : public CMenuTarget CMenuWidget(const std::string &Name, const std::string & Icon = "", const int mwidth = 30, const mn_widget_id_t &w_index = NO_WIDGET_ID); CMenuWidget(const neutrino_locale_t Name, const std::string & Icon = "", const int mwidth = 30, const mn_widget_id_t &w_index = NO_WIDGET_ID); ~CMenuWidget(); - + void ResetModules(); virtual void addItem(CMenuItem* menuItem, const bool defaultselected = false); enum @@ -610,7 +610,7 @@ class CMenuWidget : public CMenuTarget }; void addKey(neutrino_msg_t key, CMenuTarget *menue, const std::string &action); void setFooter(const struct button_label *_fbutton_label, const int _fbutton_count, bool repaint = false); - void suppressDetailsLine(bool suppress = true){show_details_line = suppress ? false : true;}; + void setNextShortcut(int sc) { nextShortcut = sc; }; int getNextShortcut() { return nextShortcut; }; }; From 7b28c80b742842f17c22b2b64054a13e69a5682c Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 12 Dec 2015 14:42:01 +0100 Subject: [PATCH 012/110] lua instances: adopt for last rebases with splitted lua source files TODO: check/fix lua functionality, not tested yet --- src/gui/lua/lua_cc_picture.cpp | 5 +++-- src/gui/lua/lua_cc_text.cpp | 13 +++++++------ src/gui/lua/lua_cc_window.cpp | 5 +++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/gui/lua/lua_cc_picture.cpp b/src/gui/lua/lua_cc_picture.cpp index d58062c7b..84eceb74b 100644 --- a/src/gui/lua/lua_cc_picture.cpp +++ b/src/gui/lua/lua_cc_picture.cpp @@ -148,7 +148,7 @@ int CLuaInstCCPicture::CCPictureHide(lua_State *L) lua_assert(lua_istable(L,1)); CLuaCCPicture *D = CCPictureCheck(L, 1); if (!D) return 0; - +#if 0 bool no_restore = false; if (!tableLookup(L, "no_restore", no_restore)) { std::string tmp = "false"; @@ -156,11 +156,12 @@ int CLuaInstCCPicture::CCPictureHide(lua_State *L) paramBoolDeprecated(L, tmp.c_str()); no_restore = (tmp == "true" || tmp == "1" || tmp == "yes"); } +#endif if (D->parent) { D->cp->setPicture(""); D->cp->paint(); } else - D->cp->hide(no_restore); + D->cp->hide(); return 0; } diff --git a/src/gui/lua/lua_cc_text.cpp b/src/gui/lua/lua_cc_text.cpp index 57b907e60..294df354d 100644 --- a/src/gui/lua/lua_cc_text.cpp +++ b/src/gui/lua/lua_cc_text.cpp @@ -98,12 +98,12 @@ int CLuaInstCCText::CCTextNew(lua_State *L) if (font_text >= SNeutrinoSettings::FONT_TYPE_COUNT || font_text < 0) font_text = SNeutrinoSettings::FONT_TYPE_MENU; - bool has_shadow = false; - if (!tableLookup(L, "has_shadow", has_shadow)) { + int shadow_mode = CC_SHADOW_OFF; + if (!tableLookup(L, "has_shadow", shadow_mode)) { std::string tmp1 = "false"; if (tableLookup(L, "has_shadow", tmp1)) paramBoolDeprecated(L, tmp1.c_str()); - has_shadow = (tmp1 == "true" || tmp1 == "1" || tmp1 == "yes"); + shadow_mode = (tmp1 == "true" || tmp1 == "1" || tmp1 == "yes"); } tableLookup(L, "color_text", color_text); @@ -142,7 +142,7 @@ int CLuaInstCCText::CCTextNew(lua_State *L) CLuaCCText **udata = (CLuaCCText **) lua_newuserdata(L, sizeof(CLuaCCText *)); *udata = new CLuaCCText(); - (*udata)->ct = new CComponentsText(x, y, dx, dy, text, mode, g_Font[font_text], pw, has_shadow, (fb_pixel_t)color_text, (fb_pixel_t)color_frame, (fb_pixel_t)color_body, (fb_pixel_t)color_shadow); + (*udata)->ct = new CComponentsText(x, y, dx, dy, text, mode, g_Font[font_text], 0 /*TODO: style not passed*/, pw, shadow_mode, (fb_pixel_t)color_text, (fb_pixel_t)color_frame, (fb_pixel_t)color_body, (fb_pixel_t)color_shadow); (*udata)->parent = pw; (*udata)->mode = mode; (*udata)->font_text = font_text; @@ -173,7 +173,7 @@ int CLuaInstCCText::CCTextHide(lua_State *L) lua_assert(lua_istable(L,1)); CLuaCCText *D = CCTextCheck(L, 1); if (!D) return 0; - +#if 0 bool no_restore = false; if (!tableLookup(L, "no_restore", no_restore)) { std::string tmp = "false"; @@ -181,11 +181,12 @@ int CLuaInstCCText::CCTextHide(lua_State *L) paramBoolDeprecated(L, tmp.c_str()); no_restore = (tmp == "true" || tmp == "1" || tmp == "yes"); } +#endif if (D->parent) { D->ct->setText("", D->mode, g_Font[D->font_text]); D->ct->paint(); } else - D->ct->hide(no_restore); + D->ct->hide(); return 0; } diff --git a/src/gui/lua/lua_cc_window.cpp b/src/gui/lua/lua_cc_window.cpp index fd08b0802..dacba8780 100644 --- a/src/gui/lua/lua_cc_window.cpp +++ b/src/gui/lua/lua_cc_window.cpp @@ -196,7 +196,7 @@ int CLuaInstCCWindow::CCWindowHide(lua_State *L) lua_assert(lua_istable(L,1)); CLuaCCWindow *D = CCWindowCheck(L, 1); if (!D) return 0; - +#if 0 bool no_restore = false; if (!tableLookup(L, "no_restore", no_restore)) { std::string tmp = "false"; @@ -204,7 +204,8 @@ int CLuaInstCCWindow::CCWindowHide(lua_State *L) paramBoolDeprecated(L, tmp.c_str()); no_restore = (tmp == "true" || tmp == "1" || tmp == "yes"); } - D->w->hide(no_restore); +#endif + D->w->hide(); return 0; } From d77b7b2995615ff89a9868e7e525ace590a6787b Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 24 Dec 2015 14:04:53 +0100 Subject: [PATCH 013/110] tmp revert: remove osd setup for gradients --- src/gui/osd_setup.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index 398ce6fac..74857f1f0 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -678,23 +678,23 @@ void COsdSetup::showOsdMenueColorSetup(CMenuWidget *menu_colors) sigc::slot0 slot_repaint = sigc::mem_fun(menu_colors, &CMenuWidget::paint); //we want to repaint after changed Option CColorChooser* chHeadcolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.menu_Head_red, &t.menu_Head_green, &t.menu_Head_blue, - &t.menu_Head_alpha, &g_settings.theme.menu_Head_gradient, colorSetupNotifier); + &t.menu_Head_alpha, colorSetupNotifier); chHeadcolor->setGradient(CColorChooser::gradient_head_body); CColorChooser* chHeadTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.menu_Head_Text_red, &t.menu_Head_Text_green, &t.menu_Head_Text_blue, - NULL, NULL, colorSetupNotifier); + NULL, colorSetupNotifier); chHeadTextcolor->setGradient(CColorChooser::gradient_head_text); CColorChooser* chContentcolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.menu_Content_red, &t.menu_Content_green, &t.menu_Content_blue, - &t.menu_Content_alpha, NULL, colorSetupNotifier); + &t.menu_Content_alpha, colorSetupNotifier); CColorChooser* chContentTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.menu_Content_Text_red, &t.menu_Content_Text_green, &t.menu_Content_Text_blue, - NULL, NULL, colorSetupNotifier); + NULL, colorSetupNotifier); CColorChooser* chContentSelectedcolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.menu_Content_Selected_red, &t.menu_Content_Selected_green, &t.menu_Content_Selected_blue, - &t.menu_Content_Selected_alpha, NULL, colorSetupNotifier); + &t.menu_Content_Selected_alpha, colorSetupNotifier); CColorChooser* chContentSelectedTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.menu_Content_Selected_Text_red, &t.menu_Content_Selected_Text_green, &t.menu_Content_Selected_Text_blue, - NULL, NULL, colorSetupNotifier); + NULL, colorSetupNotifier); CColorChooser* chContentInactivecolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.menu_Content_inactive_red, &t.menu_Content_inactive_green, &t.menu_Content_inactive_blue, - &t.menu_Content_inactive_alpha, NULL, colorSetupNotifier); + &t.menu_Content_inactive_alpha, colorSetupNotifier); CColorChooser* chContentInactiveTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.menu_Content_inactive_Text_red, &t.menu_Content_inactive_Text_green, &t.menu_Content_inactive_Text_blue, - NULL, NULL, colorSetupNotifier); + NULL, colorSetupNotifier); menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_COLORMENUSETUP_MENUHEAD)); @@ -776,11 +776,11 @@ void COsdSetup::showOsdMenueColorSetup(CMenuWidget *menu_colors) // infoviewer color CColorChooser* chInfobarcolor = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.infobar_red, - &t.infobar_green, &t.infobar_blue, &t.infobar_alpha, NULL, colorSetupNotifier); + &t.infobar_green, &t.infobar_blue, &t.infobar_alpha, colorSetupNotifier); CColorChooser* chInfobarTextcolor = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.infobar_Text_red, - &t.infobar_Text_green, &t.infobar_Text_blue, NULL, NULL, colorSetupNotifier); + &t.infobar_Text_green, &t.infobar_Text_blue, NULL, colorSetupNotifier); CColorChooser* chInfobarCASystem = new CColorChooser(LOCALE_COLORMENU_BACKGROUND, &t.infobar_casystem_red, - &t.infobar_casystem_green, &t.infobar_casystem_blue, &t.infobar_casystem_alpha, NULL, colorSetupNotifier); + &t.infobar_casystem_green, &t.infobar_casystem_blue, &t.infobar_casystem_alpha, colorSetupNotifier); menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_COLORSTATUSBAR_TEXT)); mf = new CMenuDForwarder(LOCALE_COLORMENU_BACKGROUND, true, NULL, chInfobarcolor ); @@ -832,7 +832,7 @@ void COsdSetup::showOsdMenueColorSetup(CMenuWidget *menu_colors) // colored events CColorChooser* chColored_Events = new CColorChooser(LOCALE_COLORMENU_TEXTCOLOR, &t.colored_events_red, - &t.colored_events_green, &t.colored_events_blue, NULL, NULL, colorSetupNotifier); + &t.colored_events_green, &t.colored_events_blue, NULL, colorSetupNotifier); menu_colors->addItem( new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MISCSETTINGS_COLORED_EVENTS)); @@ -1254,7 +1254,7 @@ void COsdSetup::showOsdInfoclockSetup(CMenuWidget *menu_infoclock) // digit color CColorChooser* cc = new CColorChooser(LOCALE_COLORMENU_CLOCK_TEXTCOLOR, &g_settings.theme.clock_Digit_red, &g_settings.theme.clock_Digit_green, &g_settings.theme.clock_Digit_blue, - NULL, NULL, colorSetupNotifier); + NULL, colorSetupNotifier); CMenuDForwarder* mf = new CMenuDForwarder(LOCALE_COLORMENU_CLOCK_TEXTCOLOR, !g_settings.infoClockBackground, NULL, cc); mf->setHint("", LOCALE_MENU_HINT_CLOCK_TEXTCOLOR); menu_infoclock->addItem(mf); From 6c8bd668017d4b2c3c03b7f4dce9cd78971649bd Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 19:41:16 +0100 Subject: [PATCH 014/110] CScreenSaver: add signal/slot handler OnBeforeStart(), try to fix infoclock In some constelations it is not required to enable infoclock after close screensaver. So it is possible to cotrol this from other objects. --- src/gui/screensaver.cpp | 11 ++++++----- src/gui/screensaver.h | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/screensaver.cpp b/src/gui/screensaver.cpp index 7c10a6f23..a3a3c8ef3 100644 --- a/src/gui/screensaver.cpp +++ b/src/gui/screensaver.cpp @@ -52,7 +52,6 @@ CScreenSaver::CScreenSaver() m_viewer = new CPictureViewer(); index = 0; status_mute = CAudioMute::getInstance()->getStatus(); - status_clock = InfoClock->getStatus(); } CScreenSaver::~CScreenSaver() @@ -77,12 +76,10 @@ CScreenSaver* CScreenSaver::getInstance() void CScreenSaver::Start() { + OnBeforeStart(); status_mute = CAudioMute::getInstance()->getStatus(); CAudioMute::getInstance()->enableMuteIcon(false); - status_clock = InfoClock->getStatus(); - InfoClock->enableInfoClock(false); - m_viewer->SetScaling((CPictureViewer::ScalingMode)g_settings.picviewer_scaling); m_viewer->SetVisible(g_settings.screen_StartX, g_settings.screen_EndX, g_settings.screen_StartY, g_settings.screen_EndY); @@ -117,8 +114,12 @@ void CScreenSaver::Stop() thrScreenSaver = 0; m_frameBuffer->paintBackground(); //clear entire screen - InfoClock->enableInfoClock(status_clock); + CAudioMute::getInstance()->enableMuteIcon(status_mute); + if (!OnAfterStop.empty()) + OnAfterStop(); + else + InfoClock->enableInfoClock(); } void* CScreenSaver::ScreenSaverPrg(void* arg) diff --git a/src/gui/screensaver.h b/src/gui/screensaver.h index 7f6984ee7..8be33d1ca 100644 --- a/src/gui/screensaver.h +++ b/src/gui/screensaver.h @@ -29,7 +29,7 @@ #include #include -class CScreenSaver +class CScreenSaver : public sigc::trackable { private: CFrameBuffer *m_frameBuffer; @@ -40,7 +40,6 @@ class CScreenSaver unsigned int index; bool status_mute; - bool status_clock; bool ReadDir(); void PaintPicture(); @@ -52,6 +51,8 @@ class CScreenSaver void Start(); void Stop(); + sigc::signal OnBeforeStart; + sigc::signal OnAfterStop; }; #endif // __CSCREENSAVER_H__ From 58337b71f1db7c1919646403a3502aef3dab6b5e Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 19:25:36 +0100 Subject: [PATCH 015/110] CTimeOSD: disable setHeight() in CTimeOSD, height is bound to settings --- src/gui/timeosd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/timeosd.h b/src/gui/timeosd.h index b46fdbecd..cf15b7643 100644 --- a/src/gui/timeosd.h +++ b/src/gui/timeosd.h @@ -60,5 +60,6 @@ class CTimeOSD : public CComponentsFrmClock void switchMode(int position, int duration); mode getMode() { return m_mode; }; void setMode (mode mode_) { m_mode = mode_; }; + void setHeight(const int){}//NOTE: dummy member, height is strictly bound to settings }; #endif From 0f7985c95c238016fec54cc57d169cd260545ed3 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 19:43:06 +0100 Subject: [PATCH 016/110] CAudioPlayerGui:try to fix infocklock view in audioplayer. after closed screensaver, infoclock was painted. That looks not good. This should fix this. --- src/gui/audioplayer.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/audioplayer.cpp b/src/gui/audioplayer.cpp index 23d8bdc3a..4d1e9ccc6 100644 --- a/src/gui/audioplayer.cpp +++ b/src/gui/audioplayer.cpp @@ -69,7 +69,7 @@ #include #include "gui/pictureviewer.h" extern CPictureViewer * g_PicViewer; - +#include #include #include #include @@ -334,7 +334,8 @@ int CAudioPlayerGui::show() // clear whole screen m_frameBuffer->paintBackground(); - + CInfoClock::getInstance()->block(); + CScreenSaver::getInstance()->OnAfterStop.connect(sigc::mem_fun(CInfoClock::getInstance(), &CInfoClock::block)); CVFD::getInstance()->setMode(CVFD::MODE_AUDIO); paintLCD(); @@ -848,7 +849,8 @@ int CAudioPlayerGui::show() if (m_state != CAudioPlayerGui::STOP) stop(); - + CInfoClock::getInstance()->enableInfoClock(CInfoClock::getInstance()->isRun()); + CScreenSaver::getInstance()->OnAfterStop.clear(); return ret; } From 1446f15d4b422504265dc67c83e17872f4448cf1 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 19:52:16 +0100 Subject: [PATCH 017/110] CMovieBrowser: try to fix paint of channellogo, and screenshot preview Logo was not hided before next logo was painted. Screenshot was lost after scrolling in movieinfo section (called with yellow button) --- src/gui/moviebrowser.cpp | 57 ++++++++++++++++++++++++++-------------- src/gui/moviebrowser.h | 4 +-- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 37df9ee38..590c5ed93 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -350,10 +350,11 @@ CMovieBrowser::~CMovieBrowser() clearListLines(); - if (CChannelLogo) { + if (CChannelLogo) delete CChannelLogo; - CChannelLogo = NULL; - } + + if (pic) + delete pic; } void CMovieBrowser::clearListLines() @@ -420,7 +421,7 @@ void CMovieBrowser::init(void) m_pcLastRecord = NULL; m_pcInfo = NULL; m_pcFilter = NULL; - + pic = NULL; m_windowFocus = MB_FOCUS_BROWSER; m_textTitle = g_Locale->getText(LOCALE_MOVIEBROWSER_HEAD); @@ -501,7 +502,7 @@ void CMovieBrowser::init(void) movielist.clear(); CChannelLogo = NULL; - + old_EpgId = 0; m_doRefresh = false; m_doLoadMovies = false; } @@ -1133,6 +1134,11 @@ int CMovieBrowser::exec(const char* path) void CMovieBrowser::hide(void) { //TRACE("[mb]->%s\n", __func__); + if (CChannelLogo){ + delete CChannelLogo; + CChannelLogo = NULL; + } + old_EpgId = 0; framebuffer->paintBackground(); if (m_pcFilter != NULL) m_currentFilterSelection = m_pcFilter->getSelectedLine(); @@ -1339,16 +1345,13 @@ void CMovieBrowser::refreshMovieInfo(void) bool logo_ok = (!fname.empty()); int flogo_w = 0, flogo_h = 0; if (logo_ok) { - int picw = (int)(((float)16 / (float)9) * (float)m_cBoxFrameInfo.iHeight); - int pich = m_cBoxFrameInfo.iHeight; - g_PicViewer->getSize(fname.c_str(), &flogo_w, &flogo_h); - g_PicViewer->rescaleImageDimensions(&flogo_w, &flogo_h, picw-2, pich-2); + flogo_w = (int)(((float)16 / (float)9) * (float)m_cBoxFrameInfo.iHeight); + flogo_h = m_cBoxFrameInfo.iHeight; #ifdef BOXMODEL_APOLLO /* align for hw blit */ flogo_w = ((flogo_w + 3) / 4) * 4; #endif } - m_pcInfo->setText(&m_movieSelectionHandler->epgInfo2, logo_ok ? m_cBoxFrameInfo.iWidth-flogo_w-20 : 0); static int logo_w = 0; static int logo_h = 0; @@ -1360,17 +1363,18 @@ void CMovieBrowser::refreshMovieInfo(void) short pb_hdd_offset = 104; if (show_mode == MB_SHOW_YT) pb_hdd_offset = 0; - static uint64_t old_EpgId = 0; + if (CChannelLogo && (old_EpgId != m_movieSelectionHandler->epgEpgId >>16)) { if (newHeader) - CChannelLogo->clearSavedScreen(); + CChannelLogo->clearFbData(); // reset logo screen data else CChannelLogo->hide(); delete CChannelLogo; CChannelLogo = NULL; } if (old_EpgId != m_movieSelectionHandler->epgEpgId >>16) { - CChannelLogo = new CComponentsChannelLogo(0, 0, m_movieSelectionHandler->epgChannel, m_movieSelectionHandler->epgEpgId >>16); + if (CChannelLogo == NULL) + CChannelLogo = new CComponentsChannelLogoScalable(0, 0, m_movieSelectionHandler->epgChannel, m_movieSelectionHandler->epgEpgId >>16); //TODO: add logo into header as item old_EpgId = m_movieSelectionHandler->epgEpgId >>16; } @@ -1388,6 +1392,7 @@ void CMovieBrowser::refreshMovieInfo(void) ly = m_cBoxFrameTitleRel.iY+m_cBoxFrame.iY+ (m_cBoxFrameTitleRel.iHeight-CChannelLogo->getHeight())/2; CChannelLogo->setXPos(lx - pb_hdd_offset); CChannelLogo->setYPos(ly); + CChannelLogo->hide(); CChannelLogo->paint(); newHeader = false; } @@ -1395,12 +1400,23 @@ void CMovieBrowser::refreshMovieInfo(void) if (m_settings.gui != MB_GUI_FILTER && logo_ok) { lx = m_cBoxFrameInfo.iX+m_cBoxFrameInfo.iWidth - flogo_w -14; ly = m_cBoxFrameInfo.iY - 1 + (m_cBoxFrameInfo.iHeight-flogo_h)/2; - g_PicViewer->DisplayImage(fname, lx+2, ly+1, flogo_w, flogo_h, CFrameBuffer::TM_NONE); - framebuffer->paintVLineRel(lx, ly, flogo_h+1, COL_WHITE); - framebuffer->paintVLineRel(lx+flogo_w+2, ly, flogo_h+2, COL_WHITE); - framebuffer->paintHLineRel(lx, flogo_w+2, ly, COL_WHITE); - framebuffer->paintHLineRel(lx, flogo_w+2, ly+flogo_h+1, COL_WHITE); + if (pic == NULL){ + pic = new CComponentsPicture(lx+2, ly+1, flogo_w, flogo_h, fname, NULL, CC_SHADOW_OFF, COL_MENUCONTENTSELECTED_PLUS_0); + pic->enableFrame(true, 2); + pic->enableCache(); + pic->doPaintBg(false); + }else{ + pic->setPicture(fname); + } + if (!m_movieSelectionHandler->epgInfo2.empty()) + m_pcInfo->OnAfterRefresh.connect(sigc::mem_fun(pic, &CComponentsPicture::paint0)); + else + pic->paint0(); + }else{ + delete pic; + pic = NULL; } + m_pcInfo->setText(&m_movieSelectionHandler->epgInfo2, logo_ok ? m_cBoxFrameInfo.iWidth-flogo_w-20 : 0); } void CMovieBrowser::info_hdd_level(bool paint_hdd) @@ -1711,7 +1727,7 @@ void CMovieBrowser::refreshTitle(void) CComponentsHeader header(x, y, w, h, title.c_str(), icon); header.paint(CC_SAVE_SCREEN_NO); - newHeader = true; + newHeader = header.isPainted(); info_hdd_level(true); } @@ -2981,6 +2997,7 @@ bool CMovieBrowser::showMenu(bool calledExternally) { /* first clear screen */ framebuffer->paintBackground(); + int i; /********************************************************************/ /** directory menu ******************************************************/ @@ -3129,8 +3146,8 @@ bool CMovieBrowser::showMenu(bool calledExternally) refreshLastPlayList(); refreshLastRecordList(); refreshFilterList(); - refreshMovieInfo(); refreshTitle(); + refreshMovieInfo(); refreshFoot(); refreshLCD(); } diff --git a/src/gui/moviebrowser.h b/src/gui/moviebrowser.h index 2c01809fb..94054e7f5 100644 --- a/src/gui/moviebrowser.h +++ b/src/gui/moviebrowser.h @@ -265,7 +265,7 @@ class CMovieBrowser : public CMenuTarget private: // Variables CFrameBuffer * framebuffer; - + CComponentsPicture *pic; CListFrame* m_pcBrowser; CListFrame* m_pcLastPlay; CListFrame* m_pcLastRecord; @@ -336,7 +336,7 @@ class CMovieBrowser : public CMenuTarget P_MI_MOVIE_LIST movielist; CComponentsChannelLogo* CChannelLogo; - + uint64_t old_EpgId; int movieInfoUpdateAll[MB_INFO_MAX_NUMBER]; int movieInfoUpdateAllIfDestEmptyOnly; From 42102d432d596b3831e00a33b14ea8332e8d3aeb Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 19:53:30 +0100 Subject: [PATCH 018/110] CUserMenu: using native callback to ensure paint for info clock after hide of this menu window menu->hide() handler comes too early, nice to see if clock is transparent. --- src/gui/user_menue.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/gui/user_menue.cpp b/src/gui/user_menue.cpp index 2ac1658c2..ac21a8602 100644 --- a/src/gui/user_menue.cpp +++ b/src/gui/user_menue.cpp @@ -163,15 +163,21 @@ bool CUserMenu::showUserMenu(neutrino_msg_t msg) if (menu == NULL) return true; + /* + using native callback to ensure paint for info clock after hide of this menu window + menu->hide() handler comes too early, nice to see if clock is transparent. + */ + menu->OnAfterHide.connect(sigc::mem_fun(CInfoClock::getInstance(), &CInfoClock::block)); + if (button < COL_BUTTONMAX) menu->setSelected(user_menu[button].selected); - + //show cancel button if configured if (g_settings.personalize[SNeutrinoSettings::P_UMENU_SHOW_CANCEL]) menu->addIntroItems(NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL); else menu->addItem(GenericMenuSeparator); - + bool _mode_ts = CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_ts; std::string itemstr_last("1"); @@ -454,7 +460,6 @@ bool CUserMenu::showUserMenu(neutrino_msg_t msg) extern CInfoClock *InfoClock; InfoClock->enableInfoClock(false); - // show menu if there are more than 2 items only // otherwise, we start the item directly (must be the last one) if (menu_items > 1 ) From 83026f1ff13f76e619092380ded714ba48f0f436 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 18 Nov 2015 19:54:37 +0100 Subject: [PATCH 019/110] CEpgData: try to fix channellogo scale in header --- src/gui/epgview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/epgview.cpp b/src/gui/epgview.cpp index 0c5bba700..97deca924 100644 --- a/src/gui/epgview.cpp +++ b/src/gui/epgview.cpp @@ -643,7 +643,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start int header_h = std::max(toph, logo_h); header = new CComponentsHeader(sx, sy, ox, header_h); if (pic_offx > 0) { - headerPic = new CComponentsPicture(sx+10, sy + (toph-logo_h)/2, logo_w, logo_h, lname); + headerPic = new CComponentsPicture(sx+10, sy + (header_h-logo_h)/2, logo_w, logo_h, lname); headerPic->doPaintBg(false); } std::string textAll = (!text2.empty()) ? text1 + "\n" + text2 : text1; From 23f67513b7381565cc7d267784d4f14bd7a5af83 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 19 Nov 2015 15:50:24 +0100 Subject: [PATCH 020/110] neutrino.h: remove unused methode switchClockOnOff() --- src/neutrino.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neutrino.h b/src/neutrino.h index 871454636..f2c1fc5c2 100644 --- a/src/neutrino.h +++ b/src/neutrino.h @@ -194,7 +194,7 @@ public: return lastMode; } void switchTvRadioMode(const int prev_mode = mode_unknown); - void switchClockOnOff(); + bool isMuted() {return current_muted; } void setCurrentMuted(int m) { current_muted = m; } From da786ac384cbf3afb97ad69789702658627fb795 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 19 Nov 2015 15:54:14 +0100 Subject: [PATCH 021/110] CImageInfo: try to fix paint button paint Handling with background and frame was changed --- src/gui/imageinfo.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/imageinfo.cpp b/src/gui/imageinfo.cpp index 919ec0432..596419934 100644 --- a/src/gui/imageinfo.cpp +++ b/src/gui/imageinfo.cpp @@ -148,6 +148,7 @@ int CImageInfo::exec(CMenuTarget* parent, const std::string &) //paint items cc_sub_caption->paint(false); cc_lic->paint(false); + btn_red->kill(); btn_red->paint(false); } else if((msg == CRCInput::RC_sat) || (msg == CRCInput::RC_favorites)) { @@ -187,6 +188,9 @@ void CImageInfo::ShowWindow() int h_footer = footer->getHeight(); fb_pixel_t btn_col = /*g_settings.theme.Button_gradient ? COL_BUTTON_BODY :*/ footer->getColorBody(); //TODO: Button_gradient option btn_red = new CComponentsButtonRed(10, CC_CENTERED, 250, h_footer-h_footer/4, LOCALE_BUILDINFO_MENU, footer, false , true, false, footer->getColorBody(), btn_col); + btn_red->doPaintBg(false); + btn_red->setButtonTextColor(COL_INFOBAR_SHADOW_TEXT); + btn_red->setColBodyGradient(CC_COLGRAD_OFF); } //prepare minitv From 8e99559d90941c54056cd453bc4867acf4dc8d16 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 29 Nov 2015 16:24:58 +0100 Subject: [PATCH 022/110] CComponentsWindow: add method to set header color --- src/gui/components/cc_frm_window.cpp | 2 ++ src/gui/components/cc_frm_window.h | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/components/cc_frm_window.cpp b/src/gui/components/cc_frm_window.cpp index 4be33a44a..7e39410a0 100644 --- a/src/gui/components/cc_frm_window.cpp +++ b/src/gui/components/cc_frm_window.cpp @@ -152,6 +152,7 @@ void CComponentsWindow::initVarWindow( const int& x_pos, const int& y_pos, const ccw_show_l_sideber = false; ccw_show_r_sideber = false; ccw_w_sidebar = 40; + ccw_col_head = COL_MENUCONTENT_PLUS_0; page_scroll_mode = PG_SCROLL_M_OFF; //permanent disabled here, only in body used! @@ -200,6 +201,7 @@ void CComponentsWindow::initHeader() ccw_head->setCaption(ccw_caption, ccw_align_mode); ccw_head->setContextButton(ccw_buttons); ccw_head->setCorner(corner_rad, CORNER_TOP); + ccw_head->setColorBody(ccw_col_head); } } diff --git a/src/gui/components/cc_frm_window.h b/src/gui/components/cc_frm_window.h index 2ef5351fc..407d6b261 100644 --- a/src/gui/components/cc_frm_window.h +++ b/src/gui/components/cc_frm_window.h @@ -83,6 +83,8 @@ class CComponentsWindow : public CComponentsForm bool ccw_show_r_sideber; ///width of sidebars int ccw_w_sidebar; + ///header bg color + fb_pixel_t ccw_col_head; ///initialze header object void initHeader(); @@ -159,7 +161,8 @@ class CComponentsWindow : public CComponentsForm ///set caption in header with string, see also getHeaderObject() void setWindowCaption(const std::string& text, const int& align_mode = CTextBox::NO_AUTO_LINEBREAK){ccw_caption = text; ccw_align_mode = align_mode;}; - + ///set background to header + void setWindowHeaderColor(const fb_pixel_t& color){ccw_col_head = color;} ///set caption in header from locales, see also getHeaderObject() void setWindowCaption(neutrino_locale_t locale_text, const int& align_mode = CTextBox::NO_AUTO_LINEBREAK); ///set caption alignment, see CTextBox for possible modes From 7659dd4642608bd4137d44b3d772c6b6e324ee29 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 29 Nov 2015 20:36:31 +0100 Subject: [PATCH 023/110] CComponentsWindow: add member setWindowHeaderTextColor() To modifiy header text color. --- src/gui/components/cc_frm_window.cpp | 5 +++-- src/gui/components/cc_frm_window.h | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/gui/components/cc_frm_window.cpp b/src/gui/components/cc_frm_window.cpp index 7e39410a0..3d6711df5 100644 --- a/src/gui/components/cc_frm_window.cpp +++ b/src/gui/components/cc_frm_window.cpp @@ -152,7 +152,8 @@ void CComponentsWindow::initVarWindow( const int& x_pos, const int& y_pos, const ccw_show_l_sideber = false; ccw_show_r_sideber = false; ccw_w_sidebar = 40; - ccw_col_head = COL_MENUCONTENT_PLUS_0; + ccw_col_head = COL_MENUCONTENT_PLUS_0; + ccw_col_head_text = COL_MENUHEAD_TEXT; page_scroll_mode = PG_SCROLL_M_OFF; //permanent disabled here, only in body used! @@ -198,7 +199,7 @@ void CComponentsWindow::initHeader() ccw_head->setWidth(width-2*fr_thickness); ccw_head->setPos(0, 0); ccw_head->setIcon(ccw_icon_name); - ccw_head->setCaption(ccw_caption, ccw_align_mode); + ccw_head->setCaption(ccw_caption, ccw_align_mode, ccw_col_head_text); ccw_head->setContextButton(ccw_buttons); ccw_head->setCorner(corner_rad, CORNER_TOP); ccw_head->setColorBody(ccw_col_head); diff --git a/src/gui/components/cc_frm_window.h b/src/gui/components/cc_frm_window.h index 407d6b261..120804d51 100644 --- a/src/gui/components/cc_frm_window.h +++ b/src/gui/components/cc_frm_window.h @@ -85,6 +85,8 @@ class CComponentsWindow : public CComponentsForm int ccw_w_sidebar; ///header bg color fb_pixel_t ccw_col_head; + ///header text color + fb_pixel_t ccw_col_head_text; ///initialze header object void initHeader(); @@ -160,7 +162,9 @@ class CComponentsWindow : public CComponentsForm void enableSidebar(const int& sidbar_type = CC_WINDOW_LEFT_SIDEBAR | CC_WINDOW_RIGHT_SIDEBAR); ///set caption in header with string, see also getHeaderObject() - void setWindowCaption(const std::string& text, const int& align_mode = CTextBox::NO_AUTO_LINEBREAK){ccw_caption = text; ccw_align_mode = align_mode;}; + void setWindowCaption(const std::string& text, const int& align_mode = CTextBox::NO_AUTO_LINEBREAK){ccw_caption = text; ccw_align_mode = align_mode;} + ///set header text color + void setWindowHeaderTextColor(const fb_pixel_t& color){ccw_col_head_text = color;} ///set background to header void setWindowHeaderColor(const fb_pixel_t& color){ccw_col_head = color;} ///set caption in header from locales, see also getHeaderObject() From f3d624b2bc7ae7daedfadaceeadb8e454c9f3e2a Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 24 Dec 2015 00:23:08 +0100 Subject: [PATCH 024/110] CPersonalizeGui: try to fix disabled observer item This should avoid disabling observer items inside personalize menu, because it's possible to lock out an observer item itself. In This case it's not possible to enable this item on runtime. Neutrino restart is required. This effect was observed in mode_ts if an user has tried to change settings for tv/radio switch. If all three items were disabled, it was not possible to enable observed items. NOTE: I think it's not a good idea to enable certain items in main menu or full sub menus like settings in mode_ts. ... What should a user do with that during watch a movie? Play with tuner settings, bouquet-, network-, drive settings etc.? Some users could cause harm, therefore I can't recommend to hold this current state. --- src/gui/personalize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/personalize.cpp b/src/gui/personalize.cpp index 44a5f3696..0e82548ca 100644 --- a/src/gui/personalize.cpp +++ b/src/gui/personalize.cpp @@ -630,7 +630,7 @@ int CPersonalizeGui::ShowMenuOptions(const int& widget) //found observer item and if found, then define 'this' as observer for current option chooser and run changeNotify bool is_observer = isObserver(v_item[i].widget, v_item[i].menuItem) ? true : false; CChangeObserver* observer = is_observer ? this : NULL; - CMenuOptionChooser * opt = new CMenuOptionChooser(name, p_mode, PERSONALIZE_MODE_OPTIONS, PERSONALIZE_MODE_MAX, v_item[i].menuItem->current_active, observer); + CMenuOptionChooser * opt = new CMenuOptionChooser(name, p_mode, PERSONALIZE_MODE_OPTIONS, PERSONALIZE_MODE_MAX, v_item[i].menuItem->current_active || is_observer, observer); if (is_observer) changeNotify(name, (void*)p_mode); From 6339ce481d3793d0666e97117ff42ba86dffbf0a Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 23 Nov 2015 09:44:34 +0100 Subject: [PATCH 025/110] CCDraw: try to separate parameter paint_bg from shadow paint --- src/gui/components/cc_draw.cpp | 38 ++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/gui/components/cc_draw.cpp b/src/gui/components/cc_draw.cpp index c857d0175..63f53f0a9 100644 --- a/src/gui/components/cc_draw.cpp +++ b/src/gui/components/cc_draw.cpp @@ -539,27 +539,29 @@ void CCDraw::paintFbItems(bool do_save_bg) if (fbtype == CC_FBDATA_TYPE_BACKGROUND){ frameBuffer->paintBackgroundBoxRel(x, y, fbdata.dx, fbdata.dy); } - else if (fbtype == CC_FBDATA_TYPE_SHADOW_BOX && !is_painted) { //TODO: is_painted is too global here, shadow will not paint on current instance without called kill/hide - if (fbdata.enabled) { - /* here we paint the shadow around the body - * on 1st step we check for already cached screen buffer, if true - * then restore this instead to call the paint methode. - * This could be usally, if we use existant instances of "this" object - */ - if (cc_allow_paint){ - if (fbdata.pixbuf){ - dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], paint shadow from cache...\033[0m\n", __func__, __LINE__); - frameBuffer->RestoreScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.pixbuf); - }else{ - frameBuffer->paintBoxRel(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.color, fbdata.r, fbdata.rtype); - } - //if is paint cache enabled - if (cc_paint_cache && fbdata.pixbuf == NULL) - fbdata.pixbuf = getScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy); + } + if (fbtype == CC_FBDATA_TYPE_SHADOW_BOX && !is_painted) { //TODO: is_painted is too global here, shadow will not paint on current instance without called kill/hide + if (fbdata.enabled) { + /* here we paint the shadow around the body + * on 1st step we check for already cached screen buffer, if true + * then restore this instead to call the paint methode. + * This could be usally, if we use existant instances of "this" object + */ + if (cc_allow_paint){ + if (fbdata.pixbuf){ + dprintf(DEBUG_INFO, "\033[33m[CCDraw]\t[%s - %d], paint shadow from cache...\033[0m\n", __func__, __LINE__); + frameBuffer->RestoreScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.pixbuf); + }else{ + frameBuffer->paintBoxRel(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy, fbdata.color, fbdata.r, fbdata.rtype); } + //if is paint cache enabled + if (cc_paint_cache && fbdata.pixbuf == NULL) + fbdata.pixbuf = getScreen(fbdata.x, fbdata.y, fbdata.dx, fbdata.dy); } } - else if (fbtype == CC_FBDATA_TYPE_BOX){ + } + if (paint_bg){ + if (fbtype == CC_FBDATA_TYPE_BOX){ if(cc_allow_paint) { /* here we paint the main body of box * on 1st step we check for already cached background buffer, if true From 0d05ca97432116ed45d18336aea596622175137b Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Fri, 25 Dec 2015 19:21:05 +0100 Subject: [PATCH 026/110] CInfoClock: remove shadow in transparent mode --- src/gui/infoclock.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/infoclock.cpp b/src/gui/infoclock.cpp index b41da69b4..bd28a7f21 100644 --- a/src/gui/infoclock.cpp +++ b/src/gui/infoclock.cpp @@ -60,9 +60,11 @@ void CInfoClock::initCCLockItems() if (paint_bg){ cl_col_text = COL_MENUCONTENT_TEXT; setColorBody(COL_MENUCONTENT_PLUS_0); + enableShadow(CC_SHADOW_ON, 3); }else{ cl_col_text = COL_INFOCLOCK_TEXT; setColorBody(COL_BACKGROUND_PLUS_0); + disableShadow(); } if (g_settings.infoClockSeconds) From f111ccc98e3e5bcbfc824c1c955d568fb9d9e487 Mon Sep 17 00:00:00 2001 From: "M. Liebmann" Date: Sat, 26 Dec 2015 10:50:50 +0100 Subject: [PATCH 027/110] CInfoViewerBB: try to fix missing sys scales in infoviewer Signed-off-by: M. Liebmann Signed-off-by: Thilo Graf --- src/gui/infoviewer_bb.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/infoviewer_bb.cpp b/src/gui/infoviewer_bb.cpp index bd81e93f0..c90e03dd7 100644 --- a/src/gui/infoviewer_bb.cpp +++ b/src/gui/infoviewer_bb.cpp @@ -407,19 +407,19 @@ void CInfoViewerBB::showBBButtons(const int modus) if (paint) { fb_pixel_t *pixbuf = NULL; - int buf_x = bbIconMinX; + int buf_x = bbIconMinX - 5; int buf_y = BBarY; - int buf_w = g_InfoViewer->BoxEndX-bbIconMinX; + int buf_w = g_InfoViewer->BoxEndX-buf_x; int buf_h = InfoHeightY_Info; if (modus != -1) { pixbuf = new fb_pixel_t[buf_w * buf_h]; //printf("\nbuf_x: %d, buf_y: %d, buf_w: %d, buf_h: %d, pixbuf: %p\n \n", buf_x, buf_y, buf_w, buf_h, pixbuf); frameBuffer->SaveScreen(buf_x, buf_y, buf_w, buf_h, pixbuf); - } - paintFoot(minX - g_InfoViewer->ChanInfoX); - if ((modus != -1) && (pixbuf != NULL)) { - frameBuffer->RestoreScreen(buf_x, buf_y, buf_w, buf_h, pixbuf); - delete [] pixbuf; + paintFoot(); + if (pixbuf != NULL) { + frameBuffer->RestoreScreen(buf_x, buf_y, buf_w, buf_h, pixbuf); + delete [] pixbuf; + } } int last_x = minX; for (i = BUTTON_MAX; i > 0;) { From b86586bf6847bda3ac1d7da3a5859fb20cb409a5 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 26 Dec 2015 19:20:03 +0100 Subject: [PATCH 028/110] CStreamInfo2: try to fix wrong text colors Text color was not matching for background color. In some constellations with theme settings, text is not really good readable. COL_MENUCONTENT_... requires COL_MENUCONTENT_TEXT, not COL_INFOBAR_TEXT --- src/gui/streaminfo2.cpp | 94 ++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/gui/streaminfo2.cpp b/src/gui/streaminfo2.cpp index 9fa937c87..d42532a6d 100644 --- a/src/gui/streaminfo2.cpp +++ b/src/gui/streaminfo2.cpp @@ -182,15 +182,15 @@ int CStreamInfo2::doSignalStrengthLoop () char currate[150]; snprintf(tmp_str,sizeof(tmp_str), "%s:",g_Locale->getText(LOCALE_STREAMINFO_BITRATE)); - g_Font[font_info]->RenderString(dx1 , average_bitrate_pos, offset+10, tmp_str, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString(dx1 , average_bitrate_pos, offset+10, tmp_str, COL_MENUCONTENT_TEXT); sprintf(currate, "%5llu.%02llu", rate.short_average / 1000ULL, rate.short_average % 1000ULL); frameBuffer->paintBoxRel (dx1 + average_bitrate_offset , average_bitrate_pos -dheight, sw, dheight, COL_MENUCONTENT_PLUS_0); - g_Font[font_info]->RenderString (dx1 + average_bitrate_offset , average_bitrate_pos, sw - 10, currate, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (dx1 + average_bitrate_offset , average_bitrate_pos, sw - 10, currate, COL_MENUCONTENT_TEXT); snprintf(tmp_str,sizeof(tmp_str), "(%s)",g_Locale->getText(LOCALE_STREAMINFO_AVERAGE_BITRATE)); - g_Font[font_info]->RenderString (dx1 + average_bitrate_offset + sw , average_bitrate_pos, sw *2, tmp_str, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (dx1 + average_bitrate_offset + sw , average_bitrate_pos, sw *2, tmp_str, COL_MENUCONTENT_TEXT); } if (!mp) { @@ -291,7 +291,7 @@ void CStreamInfo2::paint_signal_fe_box(int _x, int _y, int w, int h) snprintf(tname, sizeof(tname), "%s: %d: %s", g_Locale->getText(LOCALE_STREAMINFO_SIGNAL), tuner, frontend->getName()); #endif - g_Font[font_small]->RenderString(_x, _y+iheight+15, width-_x-10, tname /*tuner_name.c_str()*/, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(_x, _y+iheight+15, width-_x-10, tname /*tuner_name.c_str()*/, COL_MENUCONTENT_TEXT); sigBox_x = _x; sigBox_y = _y+iheight+15; @@ -305,17 +305,17 @@ void CStreamInfo2::paint_signal_fe_box(int _x, int _y, int w, int h) if (!mp) { frameBuffer->paintBoxRel(_x+xd*0,y1- 12,16,2, COL_RED); //red - g_Font[font_small]->RenderString(_x+20+xd*0, y1, fw*4, "BER", COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(_x+20+xd*0, y1, fw*4, "BER", COL_MENUCONTENT_TEXT); frameBuffer->paintBoxRel(_x+xd*1,y1- 12,16,2,COL_BLUE); //blue - g_Font[font_small]->RenderString(_x+20+xd*1, y1, fw*4, "SNR", COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(_x+20+xd*1, y1, fw*4, "SNR", COL_MENUCONTENT_TEXT); frameBuffer->paintBoxRel(_x+8+xd*2,y1- 12,16,2, COL_GREEN); //green - g_Font[font_small]->RenderString(_x+28+xd*2, y1, fw*4, "SIG", COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(_x+28+xd*2, y1, fw*4, "SIG", COL_MENUCONTENT_TEXT); } frameBuffer->paintBoxRel(_x+xd*3,y1- 12,16,2,COL_YELLOW); // near yellow - g_Font[font_small]->RenderString(_x+20+xd*3, y1, fw*5, "Bitrate", COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(_x+20+xd*3, y1, fw*5, "Bitrate", COL_MENUCONTENT_TEXT); sig_text_ber_x = _x + xd * 0; sig_text_snr_x = _x + 5 + xd * 1; @@ -330,9 +330,9 @@ void CStreamInfo2::paint_signal_fe_box(int _x, int _y, int w, int h) else maxmin_x = _x + 40 + xd * 3 + (fontW*4); - g_Font[font_small]->RenderString(maxmin_x, y1 + sheight + 5, fw*3, "max", COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(maxmin_x, y1 + (sheight * 2) +5, fw*3, "now", COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(maxmin_x, y1 + (sheight * 3) +5, fw*3, "min", COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(maxmin_x, y1 + sheight + 5, fw*3, "max", COL_MENUCONTENT_TEXT); + g_Font[font_small]->RenderString(maxmin_x, y1 + (sheight * 2) +5, fw*3, "now", COL_MENUCONTENT_TEXT); + g_Font[font_small]->RenderString(maxmin_x, y1 + (sheight * 3) +5, fw*3, "min", COL_MENUCONTENT_TEXT); sigBox_pos = 0; @@ -431,7 +431,7 @@ void CStreamInfo2::SignalRenderStr(unsigned int value, int _x, int _y) fw *=(fw>17)?5:6; frameBuffer->paintBoxRel(_x, _y - sheight + 5, fw, sheight -1, COL_MENUCONTENT_PLUS_0); sprintf(str,"%6u",value); - g_Font[font_small]->RenderString(_x, _y + 5, fw, str, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(_x, _y + 5, fw, str, COL_MENUCONTENT_TEXT); } void CStreamInfo2::paint (int /*mode*/) @@ -521,14 +521,14 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) //Video RESOLUTION ypos += iheight; snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_STREAMINFO_RESOLUTION)); - g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_MENUCONTENT_TEXT); snprintf(buf, sizeof(buf), "%dx%d", xres, yres); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //audio rate ypos += iheight; snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_STREAMINFO_ARATIO)); - g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_MENUCONTENT_TEXT); switch (aspectRatio) { case 0: snprintf(buf, sizeof(buf), "N/A"); @@ -548,12 +548,12 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) default: strncpy (buf, g_Locale->getText (LOCALE_STREAMINFO_ARATIO_UNKNOWN), sizeof (buf)-1); } - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //Video FRAMERATE ypos += iheight; snprintf(buf, sizeof(buf), "%s:", g_Locale->getText (LOCALE_STREAMINFO_FRAMERATE)); - g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_MENUCONTENT_TEXT); switch (framerate) { case 0: snprintf (buf,sizeof(buf), "23.976fps"); @@ -583,7 +583,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) strncpy (buf, g_Locale->getText (LOCALE_STREAMINFO_FRAMERATE_UNKNOWN), sizeof (buf)-1); break; } - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); // place for average bitrate average_bitrate_pos = ypos += iheight; //AUDIOTYPE @@ -592,7 +592,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) audioDecoder->getAudioInfo(type, layer, freq, lbitrate, mode); snprintf(buf, sizeof(buf), "%s:", g_Locale->getText (LOCALE_STREAMINFO_AUDIOTYPE)); - g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos, ypos, box_width, buf, COL_MENUCONTENT_TEXT); if(type == AUDIO_FMT_MPEG) { const int max_mode = 4; @@ -625,21 +625,21 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) } else { snprintf(buf, sizeof(buf), "%s (%d)", g_Locale->getText(LOCALE_STREAMINFO_AUDIOTYPE_UNKNOWN), freq); } - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); if (mp) { //channel ypos += iheight; if (CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_webtv) { snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_TIMERLIST_CHANNEL));//swiped locale - g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_MENUCONTENT_TEXT); snprintf(buf, sizeof(buf), "%s", channel->getName().c_str()); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); } else { snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_MOVIEBROWSER_INFO_FILE));//swiped locale - g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_MENUCONTENT_TEXT); snprintf(buf, sizeof(buf), "%s", mp->GetFile().c_str()); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); } scaling = 27000; @@ -656,19 +656,19 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) else if (CFrontend::isTerr(t.feparams.delsys)) snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_TERRESTRIALSETUP_AREA)); - g_Font[font_info]->RenderString(xpos, ypos, box_width, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString(xpos, ypos, box_width, buf, COL_MENUCONTENT_TEXT); snprintf(buf, sizeof(buf), "%s", IS_WEBTV(channel->getChannelID()) ? g_Locale->getText(LOCALE_WEBTV_HEAD) : CServiceManager::getInstance()->GetSatelliteName(channel->getSatellitePosition()).c_str()); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //channel ypos += iheight; snprintf(buf, sizeof(buf), "%s:",g_Locale->getText (LOCALE_TIMERLIST_CHANNEL));//swiped locale - g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_MENUCONTENT_TEXT); // process additional RealName if UserName exists >> uname.empty() ? realname : uname + realname snprintf(buf, sizeof(buf), "%s", (channel->getName()==channel->getRealname()) ? channel->getRealname().c_str():(channel->getName()+" << "+channel->getRealname()).c_str()); - g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString (xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //tsfrequenz ypos += iheight; @@ -678,8 +678,8 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) scaling = 15000; snprintf(buf, sizeof(buf), "%s",g_Locale->getText (LOCALE_SCANTS_FREQDATA)); - g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_INFOBAR_TEXT); - g_Font[font_info]->RenderString(xpos+spaceoffset, ypos, box_width2, t.description().c_str(), COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString(xpos, ypos, box_width, buf , COL_MENUCONTENT_TEXT); + g_Font[font_info]->RenderString(xpos+spaceoffset, ypos, box_width2, t.description().c_str(), COL_MENUCONTENT_TEXT); // paint labels int fontW = g_Font[font_small]->getWidth(); @@ -688,27 +688,27 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) //onid ypos+= sheight; snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getOriginalNetworkId(), channel->getOriginalNetworkId()); - g_Font[font_small]->RenderString(xpos, ypos, box_width, "ONid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos, ypos, box_width, "ONid:" , COL_MENUCONTENT_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //sid ypos+= sheight; snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getServiceId(), channel->getServiceId()); - g_Font[font_small]->RenderString(xpos, ypos, box_width, "Sid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos, ypos, box_width, "Sid:" , COL_MENUCONTENT_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //tsid ypos+= sheight; snprintf(buf, sizeof(buf), "0x%04X (%i)", channel->getTransportStreamId(), channel->getTransportStreamId()); - g_Font[font_small]->RenderString(xpos, ypos, box_width, "TSid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos, ypos, box_width, "TSid:" , COL_MENUCONTENT_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //pmtpid ypos+= sheight; pmt_version = channel->getPmtVersion(); snprintf(buf, sizeof(buf), "0x%04X (%i) [0x%02X]", channel->getPmtPid(), channel->getPmtPid(), pmt_version); - g_Font[font_small]->RenderString(xpos, ypos, box_width, "PMTpid:", COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos, ypos, box_width, "PMTpid:", COL_MENUCONTENT_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //vpid ypos+= sheight; @@ -717,12 +717,12 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) } else { snprintf(buf, sizeof(buf), "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); } - g_Font[font_small]->RenderString(xpos, ypos, box_width, "Vpid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos, ypos, box_width, "Vpid:" , COL_MENUCONTENT_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); //apid ypos+= sheight; - g_Font[font_small]->RenderString(xpos, ypos, box_width, "Apid(s):" , COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos, ypos, box_width, "Apid(s):" , COL_MENUCONTENT_TEXT); if (g_RemoteControl->current_PIDs.APIDs.empty()){ snprintf(buf, sizeof(buf), "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); } else { @@ -734,7 +734,7 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) g_Font[font_small]->RenderString(xpos+sw, ypos, box_width2, buf, COL_MENUHEAD_TEXT); } else{ - g_Font[font_small]->RenderString(xpos+sw, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos+sw, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); } sw = g_Font[font_small]->getRenderWidth(buf)+sw+10; if (((li+1)%4 == 0) &&(g_RemoteControl->current_PIDs.APIDs.size()-1 > li)){ // if we have lots of apids, put "intermediate" line with pids @@ -750,8 +750,8 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) snprintf(buf, sizeof(buf), "%s", g_Locale->getText(LOCALE_STREAMINFO_NOT_AVAILABLE)); else snprintf(buf, sizeof(buf), "0x%04X (%i)", g_RemoteControl->current_PIDs.PIDs.vtxtpid, g_RemoteControl->current_PIDs.PIDs.vtxtpid ); - g_Font[font_small]->RenderString(xpos, ypos, box_width, "VTXTpid:" , COL_INFOBAR_TEXT); - g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos, ypos, box_width, "VTXTpid:" , COL_MENUCONTENT_TEXT); + g_Font[font_small]->RenderString(xpos+spaceoffset, ypos, box_width2, buf, COL_MENUCONTENT_TEXT); if(box_h == 0) box_h = ypos - ypos1; yypos = ypos; @@ -838,7 +838,7 @@ void CStreamInfo2::paintCASystem(int xpos, int ypos) if(caids[ca_id] == true){ if(cryptsysteme){ ypos += iheight; - g_Font[font_info]->RenderString(xpos , ypos, box_width, "Conditional access:" , COL_INFOBAR_TEXT); + g_Font[font_info]->RenderString(xpos , ypos, box_width, "Conditional access:" , COL_MENUCONTENT_TEXT); cryptsysteme = false; } ypos += sheight; @@ -851,7 +851,7 @@ void CStreamInfo2::paintCASystem(int xpos, int ypos) std::string::size_type last_pos = casys[ca_id].find_first_not_of(tok, 0); std::string::size_type pos = casys[ca_id].find_first_of(tok, last_pos); while (std::string::npos != pos || std::string::npos != last_pos){ - g_Font[font_small]->RenderString(xpos + width_txt, ypos, box_width, casys[ca_id].substr(last_pos, pos - last_pos).c_str() , COL_INFOBAR_TEXT); + g_Font[font_small]->RenderString(xpos + width_txt, ypos, box_width, casys[ca_id].substr(last_pos, pos - last_pos).c_str() , COL_MENUCONTENT_TEXT); if(index == 0) width_txt = spaceoffset; else @@ -1001,7 +1001,7 @@ void CStreamInfo2::showSNR () { signalbox = new CSignalBox(x + 10, yypos, 240, 50, frontend); signalbox->setColorBody(COL_MENUCONTENT_PLUS_0); - signalbox->setTextColor(COL_INFOBAR_TEXT); + signalbox->setTextColor(COL_MENUCONTENT_TEXT); signalbox->doPaintBg(true); } From 4875f81491f2eb1d462e8f164a079f9febe96733 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 26 Dec 2015 21:09:00 +0100 Subject: [PATCH 029/110] CPersonalizeGui: try to fix wrong active mode after changed settings By treating of notifier methods or generally changed personalization settings of items, the values of "active" and "current_active" may differ and although that could be active = true, current_active = false, or vice versa. After restart of neutrino it would not conspicuous because activ and current_active will be equated. Otherwise it can happen, the modified items could be displayed in wrong mode at runtime. This try should fix this by writing the values from the current settings into the current_active variable. --- src/gui/personalize.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/personalize.cpp b/src/gui/personalize.cpp index 0e82548ca..ff36b8ef7 100644 --- a/src/gui/personalize.cpp +++ b/src/gui/personalize.cpp @@ -976,6 +976,9 @@ void CPersonalizeGui::addPersonalizedItems() sigc::slot0 sl = sigc::bind<0>(sigc::mem_fun1(v_item[i].menuItem, &CMenuForwarder::disableByCondition), v_item[i].condition); v_item[i].menuItem->OnPaintItem.connect(sl); v_item[i].default_selected = false; + + //value of current_active for personalized item must have value of current settings state here! + v_item[i].menuItem->current_active = (p_mode || i_mode); } //add item if it's set to visible or pin protected and allow to add an forwarder as next From 6952d85ae912ca2e005e25b7460cd8aea62e7ddd Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 27 Dec 2015 13:40:33 +0100 Subject: [PATCH 030/110] CCDraw: add signals into paintFbItems() --- src/gui/components/cc_base.h | 3 +-- src/gui/components/cc_draw.cpp | 5 +++++ src/gui/components/cc_draw.h | 8 +++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/components/cc_base.h b/src/gui/components/cc_base.h index b697deda6..d6420f0c0 100644 --- a/src/gui/components/cc_base.h +++ b/src/gui/components/cc_base.h @@ -26,7 +26,6 @@ #define __CC_BASE__ #include "cc_types.h" -#include "cc_signals.h" #include "cc_draw.h" /// Basic component class. @@ -34,7 +33,7 @@ Basic attributes and member functions for component sub classes */ -class CComponents : public CComponentsSignals, public CCDraw +class CComponents : public CCDraw { protected: diff --git a/src/gui/components/cc_draw.cpp b/src/gui/components/cc_draw.cpp index 63f53f0a9..f5c283c72 100644 --- a/src/gui/components/cc_draw.cpp +++ b/src/gui/components/cc_draw.cpp @@ -465,6 +465,9 @@ void CCDraw::enablePaintCache(bool enable) //paint framebuffer layers void CCDraw::paintFbItems(bool do_save_bg) { + //pick up signal if filled + OnBeforePaintLayers(); + //first modify background handling enableSaveBg(do_save_bg); @@ -609,6 +612,8 @@ void CCDraw::paintFbItems(bool do_save_bg) } } } + //pick up signal if filled + OnAfterPaintLayers(); } diff --git a/src/gui/components/cc_draw.h b/src/gui/components/cc_draw.h index 989a2ee5f..1381b0f31 100644 --- a/src/gui/components/cc_draw.h +++ b/src/gui/components/cc_draw.h @@ -26,6 +26,7 @@ #define __CC_DRAW__ #include "cc_types.h" +#include "cc_signals.h" #include #include #include @@ -35,7 +36,7 @@ Basic paint attributes and member functions for component classes */ -class CCDraw : public COSDFader +class CCDraw : public COSDFader, public CComponentsSignals { protected: ///pixel buffer handling, returns pixel buffer depends of given parameters @@ -294,6 +295,11 @@ class CCDraw : public COSDFader ///paint item, same like paint(CC_SAVE_SCREEN_NO) but without any argument virtual void paint0(){paint(CC_SAVE_SCREEN_NO);} + ///signal on before paint fb layers, called inside paintFbItems() + sigc::signal OnBeforePaintLayers; + ///signal on after paint fb layers, called inside paintFbItems() + sigc::signal OnAfterPaintLayers; + /*! Removes current item from screen and restore last displayed background before item was painted and From ff667dfef30163ab2a29ad6b316ee9629a3d1119 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 27 Dec 2015 19:46:14 +0100 Subject: [PATCH 031/110] Screeansaver: add optional random images --- data/locale/deutsch.locale | 2 ++ data/locale/english.locale | 2 ++ src/gui/osd_setup.cpp | 6 ++++++ src/gui/screensaver.cpp | 6 +++++- src/neutrino.cpp | 2 ++ src/system/locals.h | 2 ++ src/system/locals_intern.h | 2 ++ src/system/settings.h | 1 + 8 files changed, 22 insertions(+), 1 deletion(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 81fbb7983..182b19fab 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1344,6 +1344,7 @@ menu.hint_scrambled_message Bei aktivierter Option erscheint eine Meldung, wenn menu.hint_screen_setup Konfigurieren Sie den Bildschirmbereich für die Menüanzeige menu.hint_screensaver_delay Legen sie die Zeit (in Minuten) fest, nach der der Bildschirmschoner starten soll oder schaltet ihn aus menu.hint_screensaver_dir Wählen Sie das Verzeichnis, in dem die Bilder für Ihren Bildschirmschoner gespeichert sind +menu.hint_screensaver_random Aktviere/deaktiviere zufällige Bilderauswahl. menu.hint_screensaver_timeout Wählen Sie Die Wartezeit bis zum Bilderwechsel des Bildschirmschoners menu.hint_screensaver_setup Konfigurieren Sie die Optionen des Bildschirmschoners für den Audioplayer und den Radio-Modus menu.hint_screenshot_count Wählen Sie, wie viele Screenshots erstellt werden sollen @@ -2145,6 +2146,7 @@ screensaver.delay Verzögerung screensaver.dir Verzeichnis screensaver.menu Bildschirmschoner screensaver.off Bildschirmschoner aus +screensaver.random Zufällige Bilderwahl screensaver.timeout Bilderwechsel screensetup.lowerright grün = Bildrand unten, rechts screensetup.upperleft rot = Bildrand oben, links diff --git a/data/locale/english.locale b/data/locale/english.locale index 160a18479..020747dbf 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1344,6 +1344,7 @@ menu.hint_scrambled_message Show scrambled message, when channel cannot be decod menu.hint_screen_setup Configure screen margins menu.hint_screensaver_delay Set the time (in minutes) after which the screensaver has to start or turn it off menu.hint_screensaver_dir Select directory in which the screensaver has to start +menu.hint_screensaver_random Enable/disable random image selection. menu.hint_screensaver_timeout Select the timeout to change pictures in screensavers menu.hint_screensaver_setup Configure screensaver options for audioplayer and radio mode menu.hint_screenshot_count When no GUI on screen, you can save 1-5\nscreenshot serie @@ -2145,6 +2146,7 @@ screensaver.delay Delay screensaver.dir Directory screensaver.menu Screensaver screensaver.off Screensaver off +screensaver.random Random Images screensaver.timeout Change pictures screensetup.lowerright green = setup lower right screensetup.upperleft red = setup upper left diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index 74857f1f0..d96303e0d 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -1442,6 +1442,12 @@ void COsdSetup::showOsdScreensaverSetup(CMenuWidget *menu_screensaver) mf->setHint("", LOCALE_MENU_HINT_SCREENSAVER_DIR); menu_screensaver->addItem(mf); screensaverNotifier->addItem(mf); + + // screensaver random mode + CMenuOptionChooser* oc = new CMenuOptionChooser(LOCALE_SCREENSAVER_RANDOM, &g_settings.screensaver_random, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + oc->setHint("", LOCALE_MENU_HINT_SCREENSAVER_RANDOM); + menu_screensaver->addItem(oc); + screensaverNotifier->addItem(oc); } void COsdSetup::paintWindowSize(int w, int h) diff --git a/src/gui/screensaver.cpp b/src/gui/screensaver.cpp index a3a3c8ef3..c718b1da8 100644 --- a/src/gui/screensaver.cpp +++ b/src/gui/screensaver.cpp @@ -234,7 +234,11 @@ void CScreenSaver::PaintPicture() dprintf(DEBUG_INFO, "[CScreenSaver] %s - %d : %s\n", __func__, __LINE__, v_bg_files.at(index).c_str()); m_viewer->ShowImage(v_bg_files.at(index).c_str(), false /*unscaled*/); - index++; + if (!g_settings.screensaver_random) + index++; + else + index = rand() % v_bg_files.size(); + if(index == v_bg_files.size()) index = 0; } diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 4b087eb27..1067b98bc 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -513,6 +513,7 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.screensaver_delay = configfile.getInt32("screensaver_delay", 1); g_settings.screensaver_dir = configfile.getString("screensaver_dir", ICONSDIR); g_settings.screensaver_timeout = configfile.getInt32("screensaver_timeout", 10); + g_settings.screensaver_random = configfile.getInt32("screensaver_random", false); //vcr g_settings.vcr_AutoSwitch = configfile.getBool("vcr_AutoSwitch" , true ); @@ -1049,6 +1050,7 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32("screensaver_delay", g_settings.screensaver_delay); configfile.setString("screensaver_dir", g_settings.screensaver_dir); configfile.setInt32("screensaver_timeout", g_settings.screensaver_timeout); + configfile.setInt32("screensaver_random", g_settings.screensaver_random); //vcr configfile.setBool("vcr_AutoSwitch" , g_settings.vcr_AutoSwitch ); diff --git a/src/system/locals.h b/src/system/locals.h index 52a6f9a96..a5dbcbc49 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1371,6 +1371,7 @@ typedef enum LOCALE_MENU_HINT_SCREEN_SETUP, LOCALE_MENU_HINT_SCREENSAVER_DELAY, LOCALE_MENU_HINT_SCREENSAVER_DIR, + LOCALE_MENU_HINT_SCREENSAVER_RANDOM, LOCALE_MENU_HINT_SCREENSAVER_TIMEOUT, LOCALE_MENU_HINT_SCREENSAVER_SETUP, LOCALE_MENU_HINT_SCREENSHOT_COUNT, @@ -2172,6 +2173,7 @@ typedef enum LOCALE_SCREENSAVER_DIR, LOCALE_SCREENSAVER_MENU, LOCALE_SCREENSAVER_OFF, + LOCALE_SCREENSAVER_RANDOM, LOCALE_SCREENSAVER_TIMEOUT, LOCALE_SCREENSETUP_LOWERRIGHT, LOCALE_SCREENSETUP_UPPERLEFT, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 0cab6e897..5a0fdca0e 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1371,6 +1371,7 @@ const char * locale_real_names[] = "menu.hint_screen_setup", "menu.hint_screensaver_delay", "menu.hint_screensaver_dir", + "menu.hint_screensaver_random", "menu.hint_screensaver_timeout", "menu.hint_screensaver_setup", "menu.hint_screenshot_count", @@ -2172,6 +2173,7 @@ const char * locale_real_names[] = "screensaver.dir", "screensaver.menu", "screensaver.off", + "screensaver.random", "screensaver.timeout", "screensetup.lowerright", "screensetup.upperleft", diff --git a/src/system/settings.h b/src/system/settings.h index 775a11056..5615262c4 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -240,6 +240,7 @@ struct SNeutrinoSettings int screensaver_delay; std::string screensaver_dir; int screensaver_timeout; + int screensaver_random; //vcr int vcr_AutoSwitch; From 0b3576b4a71204de873ba97e9ac2aad609b013b0 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 27 Dec 2015 22:26:23 +0100 Subject: [PATCH 032/110] Screensaver: add option to show current time instead images --- data/locale/deutsch.locale | 8 +++-- data/locale/english.locale | 8 +++-- src/gui/osd_setup.cpp | 15 ++++++++- src/gui/screensaver.cpp | 64 ++++++++++++++++++++++++++------------ src/gui/screensaver.h | 9 +++++- src/neutrino.cpp | 4 ++- src/system/locals.h | 4 +++ src/system/locals_intern.h | 4 +++ src/system/settings.h | 1 + 9 files changed, 90 insertions(+), 27 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 182b19fab..0dbfe8820 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1344,8 +1344,9 @@ menu.hint_scrambled_message Bei aktivierter Option erscheint eine Meldung, wenn menu.hint_screen_setup Konfigurieren Sie den Bildschirmbereich für die Menüanzeige menu.hint_screensaver_delay Legen sie die Zeit (in Minuten) fest, nach der der Bildschirmschoner starten soll oder schaltet ihn aus menu.hint_screensaver_dir Wählen Sie das Verzeichnis, in dem die Bilder für Ihren Bildschirmschoner gespeichert sind +menu.hint_screensaver_mode Modus des Bilschirmschoners wählen. menu.hint_screensaver_random Aktviere/deaktiviere zufällige Bilderauswahl. -menu.hint_screensaver_timeout Wählen Sie Die Wartezeit bis zum Bilderwechsel des Bildschirmschoners +menu.hint_screensaver_timeout Wechselintervall des Bildschirmschoners menu.hint_screensaver_setup Konfigurieren Sie die Optionen des Bildschirmschoners für den Audioplayer und den Radio-Modus menu.hint_screenshot_count Wählen Sie, wie viele Screenshots erstellt werden sollen menu.hint_screenshot_cover Während der Wiedergabe von Aufnahmen kann ein Screenshot für die Vorschau im Moviebrowser erstellt werden @@ -2145,9 +2146,12 @@ scrambled_channel Verschlüsselung aktiv screensaver.delay Verzögerung screensaver.dir Verzeichnis screensaver.menu Bildschirmschoner +screensaver.mode Modus +screensaver.mode_clock Uhr +screensaver.mode_image Bilder screensaver.off Bildschirmschoner aus screensaver.random Zufällige Bilderwahl -screensaver.timeout Bilderwechsel +screensaver.timeout Wechselintervall screensetup.lowerright grün = Bildrand unten, rechts screensetup.upperleft rot = Bildrand oben, links screenshot.count Anzahl diff --git a/data/locale/english.locale b/data/locale/english.locale index 020747dbf..ac42eb630 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1344,8 +1344,9 @@ menu.hint_scrambled_message Show scrambled message, when channel cannot be decod menu.hint_screen_setup Configure screen margins menu.hint_screensaver_delay Set the time (in minutes) after which the screensaver has to start or turn it off menu.hint_screensaver_dir Select directory in which the screensaver has to start +menu.hint_screensaver_mode Select screensaver mode. menu.hint_screensaver_random Enable/disable random image selection. -menu.hint_screensaver_timeout Select the timeout to change pictures in screensavers +menu.hint_screensaver_timeout Select the timeout to changes in screensavers menu.hint_screensaver_setup Configure screensaver options for audioplayer and radio mode menu.hint_screenshot_count When no GUI on screen, you can save 1-5\nscreenshot serie menu.hint_screenshot_cover ON: When playing record, overwrite single\nscreenshot to show inside MovieBrowser @@ -2145,9 +2146,12 @@ scrambled_channel Scrambled channel screensaver.delay Delay screensaver.dir Directory screensaver.menu Screensaver +screensaver.mode Mode +screensaver.mode_clock Clock +screensaver.mode_image Images screensaver.off Screensaver off screensaver.random Random Images -screensaver.timeout Change pictures +screensaver.timeout Change interval screensetup.lowerright green = setup lower right screensetup.upperleft red = setup upper left screenshot.count Count diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index d96303e0d..6b90a8536 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -1419,6 +1419,13 @@ void COsdSetup::showOsdScreenShotSetup(CMenuWidget *menu_screenshot) menu_screenshot->addItem(mc); } +#define SCREENSAVER_MODE_OPTION_COUNT 2 +const CMenuOptionChooser::keyval SCREENSAVER_MODE_OPTIONS[SCREENSAVER_MODE_OPTION_COUNT] = +{ + { 0, LOCALE_SCREENSAVER_MODE_IMAGE }, + { 1, LOCALE_SCREENSAVER_MODE_CLOCK } +}; + void COsdSetup::showOsdScreensaverSetup(CMenuWidget *menu_screensaver) { menu_screensaver->addIntroItems(LOCALE_SCREENSAVER_MENU); @@ -1430,6 +1437,12 @@ void COsdSetup::showOsdScreensaverSetup(CMenuWidget *menu_screensaver) nc->setHint("", LOCALE_MENU_HINT_SCREENSAVER_DELAY); menu_screensaver->addItem(nc); + // screensaver mode + CMenuOptionChooser* oc = new CMenuOptionChooser(LOCALE_SCREENSAVER_MODE, &g_settings.screensaver_mode, SCREENSAVER_MODE_OPTIONS, SCREENSAVER_MODE_OPTION_COUNT, true); + oc->setHint("", LOCALE_MENU_HINT_SCREENSAVER_MODE); + menu_screensaver->addItem(oc); + screensaverNotifier->addItem(oc); + // screensaver timeout nc = new CMenuOptionNumberChooser(LOCALE_SCREENSAVER_TIMEOUT, &g_settings.screensaver_timeout, (g_settings.screensaver_delay != 0), 0, 60, NULL, CRCInput::RC_nokey, NULL, 0, 0, LOCALE_OPTIONS_OFF); nc->setNumberFormat(std::string("%d ") + g_Locale->getText(LOCALE_UNIT_SHORT_SECOND)); @@ -1444,7 +1457,7 @@ void COsdSetup::showOsdScreensaverSetup(CMenuWidget *menu_screensaver) screensaverNotifier->addItem(mf); // screensaver random mode - CMenuOptionChooser* oc = new CMenuOptionChooser(LOCALE_SCREENSAVER_RANDOM, &g_settings.screensaver_random, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + oc = new CMenuOptionChooser(LOCALE_SCREENSAVER_RANDOM, &g_settings.screensaver_random, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); oc->setHint("", LOCALE_MENU_HINT_SCREENSAVER_RANDOM); menu_screensaver->addItem(oc); screensaverNotifier->addItem(oc); diff --git a/src/gui/screensaver.cpp b/src/gui/screensaver.cpp index c718b1da8..f8b027c56 100644 --- a/src/gui/screensaver.cpp +++ b/src/gui/screensaver.cpp @@ -52,6 +52,7 @@ CScreenSaver::CScreenSaver() m_viewer = new CPictureViewer(); index = 0; status_mute = CAudioMute::getInstance()->getStatus(); + scr_clock = NULL; } CScreenSaver::~CScreenSaver() @@ -61,6 +62,8 @@ CScreenSaver::~CScreenSaver() thrScreenSaver = 0; delete m_viewer; + if (scr_clock) + delete scr_clock; } @@ -113,6 +116,12 @@ void CScreenSaver::Stop() pthread_cancel(thrScreenSaver); thrScreenSaver = 0; + if (scr_clock){ + scr_clock->Stop(); + delete scr_clock; + scr_clock = NULL; + } + m_frameBuffer->paintBackground(); //clear entire screen CAudioMute::getInstance()->enableMuteIcon(status_mute); @@ -136,12 +145,12 @@ void* CScreenSaver::ScreenSaverPrg(void* arg) { while(1) { - PScreenSaver->PaintPicture(); + PScreenSaver->paint(); sleep(g_settings.screensaver_timeout); } } else - PScreenSaver->PaintPicture(); //just paint first found picture + PScreenSaver->paint(); //just paint first found picture return 0; } @@ -219,26 +228,41 @@ bool CScreenSaver::ReadDir() } -void CScreenSaver::PaintPicture() +void CScreenSaver::paint() { - if(v_bg_files.empty()) - return; + if (g_settings.screensaver_mode == SCR_MODE_IMAGE && !v_bg_files.empty()){ - if( (index >= v_bg_files.size()) || (access(v_bg_files.at(index).c_str(), F_OK)) ) - { - ReadDir(); - index = 0; - return; + if( (index >= v_bg_files.size()) || (access(v_bg_files.at(index).c_str(), F_OK)) ) + { + ReadDir(); + index = 0; + return; + } + + dprintf(DEBUG_INFO, "[CScreenSaver] %s - %d : %s\n", __func__, __LINE__, v_bg_files.at(index).c_str()); + m_viewer->ShowImage(v_bg_files.at(index).c_str(), false /*unscaled*/); + + if (!g_settings.screensaver_random) + index++; + else + index = rand() % v_bg_files.size(); + + if(index == v_bg_files.size()) + index = 0; } + else{ + if (!scr_clock){ + scr_clock = new CComponentsFrmClock(1, 1, NULL, "%H.%M:%S", "%H.%M %S", true); + scr_clock->setClockFont(g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_NUMBER]); + scr_clock->setTextColor(COL_DARK_GRAY); + scr_clock->enableSaveBg(); + scr_clock->doPaintBg(false); + } + if (scr_clock->isPainted()) + scr_clock->Stop(); - dprintf(DEBUG_INFO, "[CScreenSaver] %s - %d : %s\n", __func__, __LINE__, v_bg_files.at(index).c_str()); - m_viewer->ShowImage(v_bg_files.at(index).c_str(), false /*unscaled*/); - - if (!g_settings.screensaver_random) - index++; - else - index = rand() % v_bg_files.size(); - - if(index == v_bg_files.size()) - index = 0; + scr_clock->kill(); + scr_clock->setPosP(rand() % 80, rand() % 90); + scr_clock->Start(); + } } diff --git a/src/gui/screensaver.h b/src/gui/screensaver.h index 8be33d1ca..865a12c08 100644 --- a/src/gui/screensaver.h +++ b/src/gui/screensaver.h @@ -28,12 +28,14 @@ #include #include #include +#include class CScreenSaver : public sigc::trackable { private: CFrameBuffer *m_frameBuffer; CPictureViewer *m_viewer; + CComponentsFrmClock *scr_clock; pthread_t thrScreenSaver; static void* ScreenSaverPrg(void *arg); vector v_bg_files; @@ -42,9 +44,14 @@ class CScreenSaver : public sigc::trackable bool status_mute; bool ReadDir(); - void PaintPicture(); + void paint(); public: + enum + { + SCR_MODE_IMAGE, + SCR_MODE_CLOCK + }; CScreenSaver(); ~CScreenSaver(); static CScreenSaver* getInstance(); diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 1067b98bc..9d68da15e 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -513,7 +513,8 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.screensaver_delay = configfile.getInt32("screensaver_delay", 1); g_settings.screensaver_dir = configfile.getString("screensaver_dir", ICONSDIR); g_settings.screensaver_timeout = configfile.getInt32("screensaver_timeout", 10); - g_settings.screensaver_random = configfile.getInt32("screensaver_random", false); + g_settings.screensaver_random = configfile.getInt32("screensaver_random", 0); + g_settings.screensaver_mode = configfile.getInt32("screensaver_mode", CScreenSaver::SCR_MODE_IMAGE); //vcr g_settings.vcr_AutoSwitch = configfile.getBool("vcr_AutoSwitch" , true ); @@ -1051,6 +1052,7 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setString("screensaver_dir", g_settings.screensaver_dir); configfile.setInt32("screensaver_timeout", g_settings.screensaver_timeout); configfile.setInt32("screensaver_random", g_settings.screensaver_random); + configfile.setInt32("screensaver_mode", g_settings.screensaver_mode); //vcr configfile.setBool("vcr_AutoSwitch" , g_settings.vcr_AutoSwitch ); diff --git a/src/system/locals.h b/src/system/locals.h index a5dbcbc49..a7c2bdc67 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1371,6 +1371,7 @@ typedef enum LOCALE_MENU_HINT_SCREEN_SETUP, LOCALE_MENU_HINT_SCREENSAVER_DELAY, LOCALE_MENU_HINT_SCREENSAVER_DIR, + LOCALE_MENU_HINT_SCREENSAVER_MODE, LOCALE_MENU_HINT_SCREENSAVER_RANDOM, LOCALE_MENU_HINT_SCREENSAVER_TIMEOUT, LOCALE_MENU_HINT_SCREENSAVER_SETUP, @@ -2172,6 +2173,9 @@ typedef enum LOCALE_SCREENSAVER_DELAY, LOCALE_SCREENSAVER_DIR, LOCALE_SCREENSAVER_MENU, + LOCALE_SCREENSAVER_MODE, + LOCALE_SCREENSAVER_MODE_CLOCK, + LOCALE_SCREENSAVER_MODE_IMAGE, LOCALE_SCREENSAVER_OFF, LOCALE_SCREENSAVER_RANDOM, LOCALE_SCREENSAVER_TIMEOUT, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 5a0fdca0e..edae0aee9 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1371,6 +1371,7 @@ const char * locale_real_names[] = "menu.hint_screen_setup", "menu.hint_screensaver_delay", "menu.hint_screensaver_dir", + "menu.hint_screensaver_mode", "menu.hint_screensaver_random", "menu.hint_screensaver_timeout", "menu.hint_screensaver_setup", @@ -2172,6 +2173,9 @@ const char * locale_real_names[] = "screensaver.delay", "screensaver.dir", "screensaver.menu", + "screensaver.mode", + "screensaver.mode_clock", + "screensaver.mode_image", "screensaver.off", "screensaver.random", "screensaver.timeout", diff --git a/src/system/settings.h b/src/system/settings.h index 5615262c4..21a4d336d 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -241,6 +241,7 @@ struct SNeutrinoSettings std::string screensaver_dir; int screensaver_timeout; int screensaver_random; + int screensaver_mode; //vcr int vcr_AutoSwitch; From 2d3b3006d0b851ff28a0a4ac80e3eeb44ef8aca0 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 21 Sep 2014 22:13:26 +0200 Subject: [PATCH 033/110] COPKGManager: craete directory /tmp/.opkg on opkg manager init This directory can be useful for usage in opkg config as cache directory option cache /tmp/.opkg --- src/gui/opkg_manager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 7bd19e588..ea54f08ff 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -87,6 +87,7 @@ COPKGManager::COPKGManager() list_installed_done = false; list_upgradeable_done = false; expert_mode = false; + CFileHelpers::createDir("/tmp/.opkg"); } COPKGManager::~COPKGManager() From 35345e2c7ec5da5102072249deac33ca9d3498b1 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 4 Oct 2014 19:24:13 +0200 Subject: [PATCH 034/110] COPKGManager: use plausible message title Here we have errors, so we should use plausible titles for message box --- src/gui/opkg_manager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index ea54f08ff..7b8a0bb15 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -140,7 +140,7 @@ int COPKGManager::exec(CMenuTarget* parent, const std::string &actionKey) std::string loc = g_Locale->getText(LOCALE_OPKG_FAILURE_UPGRADE); char rs[strlen(loc.c_str()) + 20]; snprintf(rs, sizeof(rs), loc.c_str(), r); - DisplayInfoMessage(rs); + DisplayErrorMessage(rs); } else installed = true; refreshMenu(); @@ -166,7 +166,7 @@ int COPKGManager::exec(CMenuTarget* parent, const std::string &actionKey) std::string err = g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL); char rs[strlen(err.c_str()) + 20]; snprintf(rs, sizeof(rs), err.c_str(), r); - DisplayInfoMessage(rs); + DisplayErrorMessage(rs); } else installed = true; refreshMenu(); @@ -268,7 +268,7 @@ int COPKGManager::showMenu() std::string loc = g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE); char rs[strlen(loc.c_str()) + 20]; snprintf(rs, sizeof(rs), loc.c_str(), r); - DisplayInfoMessage(rs); + DisplayErrorMessage(rs); } getPkgData(OM_LIST); @@ -357,7 +357,7 @@ void COPKGManager::getPkgData(const int pkg_content_id) FILE *f = popen(pkg_types[pkg_content_id].c_str(), "r"); if (!f) { - DisplayInfoMessage("Command failed"); + DisplayErrorMessage("Command failed"); return; } From c70c2343941eee3f8779f0f29cbe110b2403c099 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 4 Oct 2014 22:18:10 +0200 Subject: [PATCH 035/110] COPKGManager: add member showError to show handled error message on screen --- src/gui/opkg_manager.cpp | 35 +++++++++++++++++------------------ src/gui/opkg_manager.h | 1 + 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 7b8a0bb15..068d10584 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -51,7 +51,7 @@ #include #include #include - +#include /* later this can be changed to just "opkg" */ #define OPKG_CL "opkg-cl" @@ -70,10 +70,10 @@ enum static const std::string pkg_types[OM_MAX] = { - OPKG_CL " list", - OPKG_CL " list-installed", - OPKG_CL " list-upgradable", - OPKG_CL " update", + OPKG_CL " list ", + OPKG_CL " list-installed ", + OPKG_CL " list-upgradable ", + OPKG_CL " update ", OPKG_CL " upgrade ", OPKG_CL " remove ", OPKG_CL " info ", @@ -137,10 +137,7 @@ int COPKGManager::exec(CMenuTarget* parent, const std::string &actionKey) parent->hide(); int r = execCmd(actionKey, true, true); if (r) { - std::string loc = g_Locale->getText(LOCALE_OPKG_FAILURE_UPGRADE); - char rs[strlen(loc.c_str()) + 20]; - snprintf(rs, sizeof(rs), loc.c_str(), r); - DisplayErrorMessage(rs); + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_UPGRADE), strerror(errno), actionKey); } else installed = true; refreshMenu(); @@ -163,10 +160,7 @@ int COPKGManager::exec(CMenuTarget* parent, const std::string &actionKey) } int r = execCmd(pkg_types[OM_INSTALL] + force + actionKey, true, true); if (r) { - std::string err = g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL); - char rs[strlen(err.c_str()) + 20]; - snprintf(rs, sizeof(rs), err.c_str(), r); - DisplayErrorMessage(rs); + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + force + actionKey); } else installed = true; refreshMenu(); @@ -265,10 +259,7 @@ int COPKGManager::showMenu() int r = execCmd(pkg_types[OM_UPDATE]); if (r) { - std::string loc = g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE); - char rs[strlen(loc.c_str()) + 20]; - snprintf(rs, sizeof(rs), loc.c_str(), r); - DisplayErrorMessage(rs); + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE), strerror(errno), pkg_types[OM_UPDATE]); } getPkgData(OM_LIST); @@ -357,7 +348,7 @@ void COPKGManager::getPkgData(const int pkg_content_id) FILE *f = popen(pkg_types[pkg_content_id].c_str(), "r"); if (!f) { - DisplayErrorMessage("Command failed"); + showError("Internal Error", strerror(errno), pkg_types[pkg_content_id]); return; } @@ -423,3 +414,11 @@ fprintf(stderr, "execCmd(%s)\n", cmdstr); return WEXITSTATUS(r); } } + +void COPKGManager::showError(const char* local_msg, char* sys_msg, const string& command) +{ + string msg = local_msg ? string(local_msg) + "\n" : ""; + msg += string(sys_msg) + ":\n"; + msg += command; + DisplayErrorMessage(msg.c_str()); +} diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index c5f014ea5..fe9be2c71 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -68,6 +68,7 @@ class COPKGManager : public CMenuTarget void updateMenu(); void refreshMenu(); bool badpackage(std::string &s); + void showError(const char* local_msg, char* sys_msg, const std::string& command); struct pkg { std::string name; From 305511a395ca82c43b4c9192ca8fd15a48fb0472 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 4 Oct 2014 22:28:13 +0200 Subject: [PATCH 036/110] CShellWindow: apply clearer enum format declaration --- src/gui/widget/shellwindow.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/widget/shellwindow.h b/src/gui/widget/shellwindow.h index a7c05b7fd..f46efa9cd 100644 --- a/src/gui/widget/shellwindow.h +++ b/src/gui/widget/shellwindow.h @@ -36,7 +36,11 @@ class CShellWindow { public: - enum shellwindow_modes { VERBOSE = 1, ACKNOWLEDGE = 2 }; + enum shellwindow_modes + { + VERBOSE = 1, + ACKNOWLEDGE = 2 + }; CShellWindow(const std::string &cmd, const int mode = 0, int *res = NULL); ~CShellWindow(); private: From c8a4d7f6b945f1f88b30ce2d005ac214b824a67f Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 4 Oct 2014 22:53:39 +0200 Subject: [PATCH 037/110] CShellWindow: handle dynamic window position, additional paint window only if not painted --- src/gui/widget/shellwindow.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 07302b0ed..ecf95aa96 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -146,8 +146,9 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res txt += *it; } if (((lines_read == lines_max) && (lastPaint + 100000 < now)) || (lastPaint + 250000 < now)) { - textBox->setText(&txt); - textBox->paint(); + textBox->setText(&txt, textBox->getWindowsPos().iWidth, false); + if (!textBox->isPainted()) + textBox->paint(); lines_read = 0; lastPaint = now; dirty = false; @@ -161,8 +162,9 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res gettimeofday(&tv,NULL); now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); if (!ok || (r < 1 && dirty && lastPaint + 250000 < now)) { - textBox->setText(&txt); - textBox->paint(); + textBox->setText(&txt, textBox->getWindowsPos().iWidth, false); + if (!textBox->isPainted()) + textBox->paint(); lastPaint = now; dirty = false; } From 3f6eaa11a3188ac52132b1c3a8c88effb4907ab7 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 4 Oct 2014 23:40:04 +0200 Subject: [PATCH 038/110] CShellWindow: visualize of 'ready'status and simplify paint of 'ok' button --- src/gui/widget/shellwindow.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index ecf95aa96..19790edf1 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res) { @@ -170,6 +171,9 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res } } while(ok); + txt += "\n...ready"; + textBox->setText(&txt, textBox->getWindowsPos().iWidth, false); + fclose(f); int s; errno = 0; @@ -186,17 +190,14 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res CShellWindow::~CShellWindow() { if (textBox && (mode & ACKNOWLEDGE)) { - int iw, ih; - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_OKAY, &iw, &ih); - Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]; - int b_width = font->getRenderWidth(g_Locale->getText(LOCALE_MESSAGEBOX_OK)) + 36 + ih + (RADIUS_LARGE / 2); - int fh = font->getHeight(); - int b_height = std::max(fh, ih) + 8 + (RADIUS_LARGE / 2); + int b_width = 150; + int b_height = 35; int xpos = frameBuffer->getScreenWidth() - b_width; int ypos = frameBuffer->getScreenHeight() - b_height; - frameBuffer->paintBoxRel(xpos, ypos, b_width, b_height, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE); - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_OKAY, xpos + ((b_height - ih) / 2), ypos + ((b_height - ih) / 2), ih); - font->RenderString(xpos + iw + 17, ypos + fh + ((b_height - fh) / 2), b_width - (iw + 21), g_Locale->getText(LOCALE_MESSAGEBOX_OK), COL_MENUCONTENT_TEXT); + + CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_OK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); + btn.paint(); + frameBuffer->blit(); neutrino_msg_t msg; From 3408dbd833307a22792ab93c82ca340beaef310e Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 5 Oct 2014 00:13:58 +0200 Subject: [PATCH 039/110] CShellWindow: add new enum option ACKNOWLEDGE_MSG allows to show a messagebox instead a small ok button --- src/gui/widget/shellwindow.cpp | 33 ++++++++++++++++++++++----------- src/gui/widget/shellwindow.h | 3 ++- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 19790edf1..08a829895 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -34,7 +34,6 @@ #include #include -#include #include #include #include @@ -43,6 +42,7 @@ #include #include #include +#include #include CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res) { @@ -189,23 +189,34 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res CShellWindow::~CShellWindow() { - if (textBox && (mode & ACKNOWLEDGE)) { - int b_width = 150; - int b_height = 35; - int xpos = frameBuffer->getScreenWidth() - b_width; - int ypos = frameBuffer->getScreenHeight() - b_height; + if (textBox){ + bool exit = false; + if (mode & ACKNOWLEDGE){ + int b_width = 150; + int b_height = 35; + int xpos = frameBuffer->getScreenWidth() - b_width; + int ypos = frameBuffer->getScreenHeight() - b_height; - CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_OK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); - btn.paint(); + CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_OK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); + btn.paint(); + } + else if (mode & ACKNOWLEDGE_MSG){ + DisplayInfoMessage("...ready. Please press OK"); + exit = true; + } frameBuffer->blit(); neutrino_msg_t msg; neutrino_msg_data_t data; uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]); - do - g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); - while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout); + + if (!exit) + { + do + g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); + while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout); + } frameBuffer->Clear(); frameBuffer->blit(); diff --git a/src/gui/widget/shellwindow.h b/src/gui/widget/shellwindow.h index f46efa9cd..ee6cb3953 100644 --- a/src/gui/widget/shellwindow.h +++ b/src/gui/widget/shellwindow.h @@ -39,7 +39,8 @@ class CShellWindow enum shellwindow_modes { VERBOSE = 1, - ACKNOWLEDGE = 2 + ACKNOWLEDGE = 2, + ACKNOWLEDGE_MSG = 4 }; CShellWindow(const std::string &cmd, const int mode = 0, int *res = NULL); ~CShellWindow(); From 86e35add16990b519e1e7e28b9de60775f154862 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 5 Oct 2014 00:24:27 +0200 Subject: [PATCH 040/110] COPKGManager: use ACKNOWLEDGE_MSG to show info message --- src/gui/opkg_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 068d10584..287942a6b 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -404,7 +404,7 @@ fprintf(stderr, "execCmd(%s)\n", cmdstr); if (verbose) { cmd += " 2>&1"; int res; - CShellWindow(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE : 0), &res); + CShellWindow(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res); return res; } else { cmd += " 2>/dev/null >&2"; From f41d4cd97338e2963c42f6f89a90d659dad12bdd Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 5 Oct 2014 01:00:51 +0200 Subject: [PATCH 041/110] CShellWindow: remove useless framebuffer callings Not to see here a reason for call of framebuffer methods. This is already done by textbox object. --- src/gui/widget/shellwindow.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 08a829895..fc9d53905 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -205,8 +205,6 @@ CShellWindow::~CShellWindow() exit = true; } - frameBuffer->blit(); - neutrino_msg_t msg; neutrino_msg_data_t data; uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]); @@ -217,9 +215,6 @@ CShellWindow::~CShellWindow() g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout); } - - frameBuffer->Clear(); - frameBuffer->blit(); } if (textBox) { textBox->hide(); From dbfa0859cff33e6f979f7f565760c8f6b749a8da Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 5 Oct 2014 01:41:21 +0200 Subject: [PATCH 042/110] CShellWindow: clean up constructor/destructor Most tasks of this class were dispersed in the constructor and destructor. Tasks are better placed in Members. --- src/gui/widget/shellwindow.cpp | 40 ++++++++++++++++++++++++---------- src/gui/widget/shellwindow.h | 6 ++++- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index fc9d53905..962870d03 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -41,15 +41,24 @@ #include #include #include -#include #include #include -CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res) { - pid_t pid; - textBox = NULL; +CShellWindow::CShellWindow(const std::string &Command, const int Mode, int *Res) +{ + textBox = NULL; + frameBuffer = CFrameBuffer::getInstance(); + + command = Command; + mode = Mode; + res = Res; + + exec(); +} + +void CShellWindow::exec() +{ std::string cmd; - mode = _mode; if (!(mode & VERBOSE)){ cmd = "PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin ; export PATH ; " + command + " 2>/dev/null >&2"; int r = system(cmd.c_str()); @@ -62,6 +71,7 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res return; } + pid_t pid; cmd = command + " 2>&1"; FILE *f = my_popen(pid, cmd.c_str(), "r"); if (!f) { @@ -70,7 +80,6 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res return; } Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]; - frameBuffer = CFrameBuffer::getInstance(); unsigned int lines_max = frameBuffer->getScreenHeight() / font->getHeight(); list lines; CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenY(), frameBuffer->getScreenWidth(), frameBuffer->getScreenHeight()); @@ -185,9 +194,11 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res else *res = WEXITSTATUS(s); } + + showResult(); } -CShellWindow::~CShellWindow() +void CShellWindow::showResult() { if (textBox){ bool exit = false; @@ -201,7 +212,10 @@ CShellWindow::~CShellWindow() btn.paint(); } else if (mode & ACKNOWLEDGE_MSG){ - DisplayInfoMessage("...ready. Please press OK"); + if (*res == -1) + DisplayErrorMessage("Please press button"); + else + DisplayInfoMessage("...ready. Please press OK"); exit = true; } @@ -215,9 +229,13 @@ CShellWindow::~CShellWindow() g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout); } - } - if (textBox) { + textBox->hide(); - delete textBox; } } + +CShellWindow::~CShellWindow() +{ + if (textBox) + delete textBox; +} diff --git a/src/gui/widget/shellwindow.h b/src/gui/widget/shellwindow.h index ee6cb3953..130c7f8ce 100644 --- a/src/gui/widget/shellwindow.h +++ b/src/gui/widget/shellwindow.h @@ -42,12 +42,16 @@ class CShellWindow ACKNOWLEDGE = 2, ACKNOWLEDGE_MSG = 4 }; - CShellWindow(const std::string &cmd, const int mode = 0, int *res = NULL); + CShellWindow(const std::string &Command, const int Mode = 0, int* Res = NULL); ~CShellWindow(); private: int mode; + std::string command; + int* res; CFrameBuffer *frameBuffer; CTextBox *textBox; + void exec(); + void showResult(); }; #endif From c4e5a9f95c176bca4bae61e5fc11fbb63c33ac69 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 10 Nov 2014 10:39:53 +0100 Subject: [PATCH 043/110] COPKGManager: use and apply namespace std --- src/gui/opkg_manager.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 287942a6b..c55018c30 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -55,6 +55,8 @@ /* later this can be changed to just "opkg" */ #define OPKG_CL "opkg-cl" +using namespace std; + enum { OM_LIST, @@ -68,7 +70,7 @@ enum OM_MAX }; -static const std::string pkg_types[OM_MAX] = +static const string pkg_types[OM_MAX] = { OPKG_CL " list ", OPKG_CL " list-installed ", @@ -94,7 +96,7 @@ COPKGManager::~COPKGManager() { } -int COPKGManager::exec(CMenuTarget* parent, const std::string &actionKey) +int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) { int res = menu_return::RETURN_REPAINT; @@ -145,11 +147,11 @@ int COPKGManager::exec(CMenuTarget* parent, const std::string &actionKey) return res; } - std::map::iterator it = pkg_map.find(actionKey); + map::iterator it = pkg_map.find(actionKey); if (it != pkg_map.end()) { if (parent) parent->hide(); - std::string force = ""; + string force = ""; if (it->second.installed && !it->second.upgradable) { char l[200]; snprintf(l, sizeof(l), g_Locale->getText(LOCALE_OPKG_MESSAGEBOX_REINSTALL), actionKey.c_str()); @@ -225,7 +227,7 @@ void COPKGManager::updateMenu() bool upgradesAvailable = false; getPkgData(OM_LIST_INSTALLED); getPkgData(OM_LIST_UPGRADEABLE); - for (std::map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) { + for (map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) { if (badpackage(it->second.name)) continue; it->second.forwarder->iconName_Info_right = ""; @@ -280,7 +282,7 @@ int COPKGManager::showMenu() menu->addKey(CRCInput::RC_red, this, "rc_red"); pkg_vec.clear(); - for (std::map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) { + for (map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) { if (badpackage(it->second.name)) continue; it->second.forwarder = new CMenuForwarder(it->second.desc, true, NULL , this, it->second.name.c_str()); @@ -334,14 +336,14 @@ void COPKGManager::getPkgData(const int pkg_content_id) if (list_installed_done) return; list_installed_done = true; - for (std::map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) + for (map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) it->second.installed = false; break; case OM_LIST_UPGRADEABLE: if (list_upgradeable_done) return; list_upgradeable_done = true; - for (std::map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) + for (map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) it->second.upgradable = false; break; } @@ -361,7 +363,7 @@ void COPKGManager::getPkgData(const int pkg_content_id) std::string line(buf); trim(line); - std::string name = getBlankPkgName(line); + string name = getBlankPkgName(line); switch (pkg_content_id) { case OM_LIST: { @@ -369,13 +371,13 @@ void COPKGManager::getPkgData(const int pkg_content_id) break; } case OM_LIST_INSTALLED: { - std::map::iterator it = pkg_map.find(name); + map::iterator it = pkg_map.find(name); if (it != pkg_map.end()) it->second.installed = true; break; } case OM_LIST_UPGRADEABLE: { - std::map::iterator it = pkg_map.find(name); + map::iterator it = pkg_map.find(name); if (it != pkg_map.end()) it->second.upgradable = true; break; @@ -389,7 +391,7 @@ void COPKGManager::getPkgData(const int pkg_content_id) pclose(f); } -std::string COPKGManager::getBlankPkgName(const std::string& line) +string COPKGManager::getBlankPkgName(const string& line) { size_t l_pos = line.find(" "); if (l_pos != string::npos) @@ -400,7 +402,7 @@ std::string COPKGManager::getBlankPkgName(const std::string& line) int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) { fprintf(stderr, "execCmd(%s)\n", cmdstr); - std::string cmd(cmdstr); + string cmd(cmdstr); if (verbose) { cmd += " 2>&1"; int res; From 1e8d19aeef2c558fef6c7f891af41f71efd04c45 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 9 Nov 2014 23:02:51 +0100 Subject: [PATCH 044/110] COPKGManager: use general options for cache, temp dir and logging cache dir option not required assigned in config file. Note: existing option "cache" in opkg config file must be removed now, otherwise it could hail error log messages and gui package listing could be garbled! Not nice now, but it's one step for an unified configure handling. --- src/gui/opkg_manager.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index c55018c30..3eb911c8c 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -5,7 +5,7 @@ OPKG-Manager Class for Neutrino-GUI Implementation: - Copyright (C) 2012 T. Graf 'dbt' + Copyright (C) 2012-2014 T. Graf 'dbt' www.dbox2-tuning.net Adaptions: @@ -54,6 +54,7 @@ #include /* later this can be changed to just "opkg" */ #define OPKG_CL "opkg-cl" +#define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=/tmp/.opkg " using namespace std; @@ -76,10 +77,10 @@ static const string pkg_types[OM_MAX] = OPKG_CL " list-installed ", OPKG_CL " list-upgradable ", OPKG_CL " update ", - OPKG_CL " upgrade ", - OPKG_CL " remove ", + OPKG_CL OPKG_CL_CONFIG_OPTIONS " upgrade ", + OPKG_CL OPKG_CL_CONFIG_OPTIONS " remove ", OPKG_CL " info ", - OPKG_CL " install " + OPKG_CL OPKG_CL_CONFIG_OPTIONS " install " }; COPKGManager::COPKGManager() From 77002eb83924e40f67987879c783b510cf5e6b2f Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 11 Nov 2014 10:48:08 +0100 Subject: [PATCH 045/110] COPKGManager: allow update and usage of multiple package sources This allows to use more than one package adress via config file. Example configuration in /etc/opkg/opkg.conf: ... src packages http://www.yourserver.org/pkgs/packages src local 192.168.1.2/pkgs/local ... After Update, all packeges will be listed in the manager list and can be installed, updated ... --- src/gui/opkg_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 3eb911c8c..b4a88e93b 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -76,7 +76,7 @@ static const string pkg_types[OM_MAX] = OPKG_CL " list ", OPKG_CL " list-installed ", OPKG_CL " list-upgradable ", - OPKG_CL " update ", + OPKG_CL " -A update ", OPKG_CL OPKG_CL_CONFIG_OPTIONS " upgrade ", OPKG_CL OPKG_CL_CONFIG_OPTIONS " remove ", OPKG_CL " info ", From 6942173bf77609e1df73912f66238f44f2fa9c11 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 13 Nov 2014 12:01:44 +0100 Subject: [PATCH 046/110] COPKGManager: add function to get status for new package updates --- src/gui/opkg_manager.cpp | 21 +++++++++++++++++++++ src/gui/opkg_manager.h | 1 + 2 files changed, 22 insertions(+) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index b4a88e93b..e05486e40 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -250,6 +250,27 @@ void COPKGManager::updateMenu() menu->setFooter(COPKGManagerFooterButtons, COPKGManagerFooterButtonCount); } +bool COPKGManager::hasUpdates() +{ + if (!hasOpkgSupport()) + return false; + + bool ret = false; + + getPkgData(OM_LIST); + getPkgData(OM_LIST_UPGRADEABLE); + + for (map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++){ + if (it->second.upgradable){ + dprintf(DEBUG_INFO, "[neutrino opkg] Update packages available...\n"); + ret = true; + } + } + + pkg_map.clear(); + return ret; +} + void COPKGManager::refreshMenu() { list_installed_done = false, list_upgradeable_done = false; diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index fe9be2c71..bfbda558f 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -86,5 +86,6 @@ class COPKGManager : public CMenuTarget int exec(CMenuTarget* parent, const std::string & actionKey); static bool hasOpkgSupport(); + bool hasUpdates(); }; #endif From a8376a5f8a3fe58a179b9c692c92131b31f1f6a7 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 13 Nov 2014 12:06:29 +0100 Subject: [PATCH 047/110] COPKGManager: use my_popen instead popen popen causes some errors after flash update check --- src/gui/opkg_manager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index e05486e40..23d899b99 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -47,7 +47,7 @@ #include #include #include -#include + #include #include #include @@ -370,7 +370,8 @@ void COPKGManager::getPkgData(const int pkg_content_id) break; } - FILE *f = popen(pkg_types[pkg_content_id].c_str(), "r"); + pid_t pid = 0; + FILE *f = my_popen(pid, pkg_types[pkg_content_id].c_str(), "r"); if (!f) { showError("Internal Error", strerror(errno), pkg_types[pkg_content_id]); return; From 6a06d5cdc1893d6f306840150595c384252525ab Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 23 Nov 2014 16:44:30 +0100 Subject: [PATCH 048/110] COPKGManager: use fclose instead pclose my_popen returns a stream pointed to a file descriptor NOTE: documentation for some bent functions in helpers.cpp would be nice! --- src/gui/opkg_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 23d899b99..546b55f7b 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -411,7 +411,7 @@ void COPKGManager::getPkgData(const int pkg_content_id) } } - pclose(f); + fclose(f); } string COPKGManager::getBlankPkgName(const string& line) From eb6f972f603eab0074500f3dca8435aec18c033d Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 22 Nov 2014 22:20:49 +0100 Subject: [PATCH 049/110] COPKGManager: add member doUpdate() --- src/gui/opkg_manager.cpp | 14 +++++++++----- src/gui/opkg_manager.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 546b55f7b..e6d062992 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -271,6 +271,14 @@ bool COPKGManager::hasUpdates() return ret; } +void COPKGManager::doUpdate() +{ + int r = execCmd(pkg_types[OM_UPDATE]); + if (r) { + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE), strerror(errno), pkg_types[OM_UPDATE]); + } +} + void COPKGManager::refreshMenu() { list_installed_done = false, list_upgradeable_done = false; @@ -280,11 +288,7 @@ void COPKGManager::refreshMenu() { int COPKGManager::showMenu() { installed = false; - - int r = execCmd(pkg_types[OM_UPDATE]); - if (r) { - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE), strerror(errno), pkg_types[OM_UPDATE]); - } + doUpdate(); getPkgData(OM_LIST); getPkgData(OM_LIST_UPGRADEABLE); diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index bfbda558f..4404666c8 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -69,6 +69,7 @@ class COPKGManager : public CMenuTarget void refreshMenu(); bool badpackage(std::string &s); void showError(const char* local_msg, char* sys_msg, const std::string& command); + void doUpdate(); struct pkg { std::string name; From 6feca09a07e055c0d1bc8ec5bb54328d44bf3f37 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 24 Nov 2014 09:05:03 +0100 Subject: [PATCH 050/110] locales: remove format tags in opkg manager messages Most messages can shows more details after evaluation of shellmessages. --- data/locale/deutsch.locale | 6 +++--- data/locale/english.locale | 6 +++--- data/locale/nederlands.locale | 6 +++--- data/locale/slovak.locale | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 0dbfe8820..7a74eec2e 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1860,9 +1860,9 @@ opkg.button.expert_on Experten-Modus opkg.button.info Paket-Informationen opkg.button.install Paket installieren opkg.button.uninstall Paket entfernen -opkg.failure.install Installation fehlgeschlagen (%d) -opkg.failure.update Update fehlgeschlagen (%d) -opkg.failure.upgrade Upgrade fehlgeschlagen (%d) +opkg.failure.install Installation fehlgeschlagen +opkg.failure.update Update fehlgeschlagen +opkg.failure.upgrade Upgrade fehlgeschlagen opkg.messagebox.reinstall %s erneut installieren? opkg.messagebox.remove %s entfernen? opkg.success.install Installation erfolgreich, Neustart von Neutrino kann erforderlich sein. diff --git a/data/locale/english.locale b/data/locale/english.locale index ac42eb630..a6d844d6f 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1860,9 +1860,9 @@ opkg.button.expert_on Expert mode opkg.button.info Package information opkg.button.install Install package opkg.button.uninstall Uninstall package -opkg.failure.install Install failed (%d) -opkg.failure.update Update failed (%d) -opkg.failure.upgrade Upgrade failed (%d) +opkg.failure.install Install failed +opkg.failure.update Update failed +opkg.failure.upgrade Upgrade failed opkg.messagebox.reinstall Re-install %s? opkg.messagebox.remove Remove %s? opkg.success.install Install successful, restart of Neutrino might be required. diff --git a/data/locale/nederlands.locale b/data/locale/nederlands.locale index 3c1f70fbb..c113e5bc6 100644 --- a/data/locale/nederlands.locale +++ b/data/locale/nederlands.locale @@ -1751,9 +1751,9 @@ opkg.button.expert_on Expert modus opkg.button.info Pakket info opkg.button.install Installeer pakket opkg.button.uninstall Deinstaleer pakket -opkg.failure.install installatie mislukt (%d) -opkg.failure.update Update mislukt (%d) -opkg.failure.upgrade Upgrade mislukt (%d) +opkg.failure.install installatie mislukt +opkg.failure.update Update mislukt +opkg.failure.upgrade Upgrade mislukt opkg.messagebox.reinstall Herinstalleer %s? opkg.messagebox.remove Wissen%s? opkg.success.install installatie succesvol, herstart van Neutrino mogelijk vereist. diff --git a/data/locale/slovak.locale b/data/locale/slovak.locale index d4b0cdc35..5dee3460b 100644 --- a/data/locale/slovak.locale +++ b/data/locale/slovak.locale @@ -1842,9 +1842,9 @@ opkg.button.expert_on Expertný mód opkg.button.info Informácia balíčka opkg.button.install Inštalovať balíček opkg.button.uninstall Odstrániť balíček -opkg.failure.install Chyba inštalácie (%d) -opkg.failure.update Chyba aktualizácie (%d) -opkg.failure.upgrade Chyba aktualizovania (%d) +opkg.failure.install inštalácia zlyhala +opkg.failure.update aktualizácie zlyhala +opkg.failure.upgrade Upgrade zlyhalo opkg.messagebox.reinstall Preinštalovať %s? opkg.messagebox.remove Odstrániť %s? opkg.success.install Inštalácia v poriadku, reštart Neutrina bude žiadúci. From 524b91a402c6a997fdb3ef4f5e1ef46816940927 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 24 Nov 2014 09:06:33 +0100 Subject: [PATCH 051/110] COPKGManager: use shell output to generate error messages for gui --- src/gui/opkg_manager.cpp | 59 ++++++++++++++++++++++++++++++---------- src/gui/opkg_manager.h | 4 +-- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index e6d062992..084bf07bc 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -271,12 +271,14 @@ bool COPKGManager::hasUpdates() return ret; } -void COPKGManager::doUpdate() +int COPKGManager::doUpdate() { int r = execCmd(pkg_types[OM_UPDATE]); - if (r) { - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE), strerror(errno), pkg_types[OM_UPDATE]); + if (r == -1) { + DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE)); +// showError(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE), strerror(errno), pkg_types[OM_UPDATE]); } + return r; } void COPKGManager::refreshMenu() { @@ -428,26 +430,55 @@ string COPKGManager::getBlankPkgName(const string& line) int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) { -fprintf(stderr, "execCmd(%s)\n", cmdstr); - string cmd(cmdstr); + fprintf(stderr, "execCmd(%s)\n", cmdstr); + string cmd = string(cmdstr); + int res = 0; + bool has_err = false; + string err_msg = ""; if (verbose) { cmd += " 2>&1"; - int res; CShellWindow(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res); - return res; } else { - cmd += " 2>/dev/null >&2"; - int r = my_system(3, "/bin/sh", "-c", cmd.c_str()); - if (r == -1) - return r; - return WEXITSTATUS(r); + cmd += " 2>&1"; + pid_t pid = 0; + FILE *f = my_popen(pid, cmd.c_str(), "r"); + if (!f) { + showError("OPKG-Error!", strerror(errno), cmd); + return -1; + } + char buf[256]; + while (fgets(buf, sizeof(buf), f)) + { + string line(buf); + trim(line); + dprintf(DEBUG_INFO, "[neutrino opkg] %s [error %d]\n", line.c_str(), has_err); + + //check for collected errors and build a message for screen if errors available + if (has_err){ + dprintf(DEBUG_NORMAL, "[neutrino opkg] %s \n", line.c_str()); + size_t pos1 = line.find(" * opkg_"); + string str = line.substr(pos1, line.length()-pos1); + err_msg += str.replace(pos1, 8,"") + "\n"; + }else{ + size_t pos2 = line.find("Collected errors:"); + if (pos2 != string::npos) + has_err = true; + } + } + fclose(f); } + if (has_err){ + DisplayErrorMessage(err_msg.c_str()); + return -1; + } + + return res; } -void COPKGManager::showError(const char* local_msg, char* sys_msg, const string& command) +void COPKGManager::showError(const char* local_msg, char* err_msg, const string& command) { string msg = local_msg ? string(local_msg) + "\n" : ""; - msg += string(sys_msg) + ":\n"; + msg += string(err_msg) + ":\n"; msg += command; DisplayErrorMessage(msg.c_str()); } diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 4404666c8..46d7c8b74 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -68,8 +68,8 @@ class COPKGManager : public CMenuTarget void updateMenu(); void refreshMenu(); bool badpackage(std::string &s); - void showError(const char* local_msg, char* sys_msg, const std::string& command); - void doUpdate(); + void showError(const char* local_msg, char* err_msg, const std::string& command); + int doUpdate(); struct pkg { std::string name; From 14779cce55acffdaf0dc175afe1c12247effcf82 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 24 Nov 2014 09:10:48 +0100 Subject: [PATCH 052/110] CShellWindow: evaluate error output for plausible message output --- src/gui/widget/shellwindow.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 962870d03..e9771be34 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -212,11 +212,12 @@ void CShellWindow::showResult() btn.paint(); } else if (mode & ACKNOWLEDGE_MSG){ - if (*res == -1) + if (*res != 0){ DisplayErrorMessage("Please press button"); - else + }else{ DisplayInfoMessage("...ready. Please press OK"); - exit = true; + exit = true; + } } neutrino_msg_t msg; From 04ad939ea74bf39261b1183958ed818851c93464 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 24 Nov 2014 11:17:28 +0100 Subject: [PATCH 053/110] CShellWindow: optimize error review after error message Show close button in window, give user possibility to read error listing before close the window! --- src/gui/widget/shellwindow.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index e9771be34..1f7f27b1a 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -201,25 +201,31 @@ void CShellWindow::exec() void CShellWindow::showResult() { if (textBox){ + bool show_button = false; bool exit = false; - if (mode & ACKNOWLEDGE){ - int b_width = 150; - int b_height = 35; - int xpos = frameBuffer->getScreenWidth() - b_width; - int ypos = frameBuffer->getScreenHeight() - b_height; - CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_OK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); - btn.paint(); + if (mode & ACKNOWLEDGE){ + show_button = true; } else if (mode & ACKNOWLEDGE_MSG){ if (*res != 0){ DisplayErrorMessage("Please press button"); + show_button = true; }else{ DisplayInfoMessage("...ready. Please press OK"); exit = true; } } + if (show_button){ + int b_width = 150; + int b_height = 35; + int xpos = frameBuffer->getScreenWidth() - b_width; + int ypos = frameBuffer->getScreenHeight() - b_height; + CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_OK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); + btn.paint(); + } + neutrino_msg_t msg; neutrino_msg_data_t data; uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]); From 3abd9c8e77140551a9234245b67667bf43109603 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 24 Nov 2014 11:37:38 +0100 Subject: [PATCH 054/110] COPKGManager: add possibility to install package from single package file --- src/gui/opkg_manager.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 084bf07bc..d8ba77a38 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -43,7 +43,7 @@ #include #include #include - +#include #include #include #include @@ -135,6 +135,27 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) updateMenu(); return res; } + if (actionKey == "local_package") { + if (parent) + parent->hide(); + CFileFilter fileFilter; + fileFilter.addFilter("opk"); + + CFileBrowser fileBrowser; + fileBrowser.Filter = &fileFilter; + + if (fileBrowser.exec(g_settings.update_dir.c_str())) + { + string pgk_name = fileBrowser.getSelectedFile()->Name; + int r = execCmd(pkg_types[OM_INSTALL] + pgk_name, true, true); + if (r) { + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pgk_name); + } else + installed = true; + refreshMenu(); + } + return res; + } if(actionKey == pkg_types[OM_UPGRADE]) { if (parent) parent->hide(); @@ -298,9 +319,16 @@ int COPKGManager::showMenu() menu = new CMenuWidget(g_Locale->getText(LOCALE_SERVICEMENU_UPDATE), NEUTRINO_ICON_UPDATE, width, MN_WIDGET_ID_SOFTWAREUPDATE); menu->addIntroItems(LOCALE_OPKG_TITLE, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_BACK, CMenuWidget::BRIEF_HINT_YES); + //upgrade all installed packages upgrade_forwarder = new CMenuForwarder(LOCALE_OPKG_UPGRADE, true, NULL , this, pkg_types[OM_UPGRADE].c_str(), CRCInput::RC_red); upgrade_forwarder->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG_UPGRADE); menu->addItem(upgrade_forwarder); + + //select and install local package + CMenuForwarder *local; + local = new CMenuForwarder("Install Local Package" , true, NULL, this, "local_package", CRCInput::RC_green); + menu->addItem(local); + menu->addItem(GenericMenuSeparatorLine); menu_offset = menu->getItemsCount(); From cd7f4bc79c33afcfcb8864df021cfb7681f7467a Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 25 Nov 2014 11:31:30 +0100 Subject: [PATCH 055/110] CShellWindow: use internal debug functionality, set init value for pid --- src/gui/widget/shellwindow.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 1f7f27b1a..a414aeaa7 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -43,6 +43,7 @@ #include #include #include +#include CShellWindow::CShellWindow(const std::string &Command, const int Mode, int *Res) { @@ -67,18 +68,21 @@ void CShellWindow::exec() *res = r; else *res = WEXITSTATUS(r); + dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] Error! system returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str()); } return; } - pid_t pid; + pid_t pid = 0; cmd = command + " 2>&1"; FILE *f = my_popen(pid, cmd.c_str(), "r"); if (!f) { if (res) *res = -1; + dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] Error! my_popen returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str()); return; } + Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]; unsigned int lines_max = frameBuffer->getScreenHeight() / font->getHeight(); list lines; From 9f565a2dd0584560bde1924913ce1da99b2bdac1 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Fri, 22 May 2015 22:28:04 +0200 Subject: [PATCH 056/110] CShellWindow: use full screen for shell window --- src/gui/widget/shellwindow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index a414aeaa7..f42682d70 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -84,9 +84,11 @@ void CShellWindow::exec() } Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]; - unsigned int lines_max = frameBuffer->getScreenHeight() / font->getHeight(); + int h_shell = frameBuffer->getScreenHeight(true)-1; + int w_shell = frameBuffer->getScreenWidth(true)-1; + unsigned int lines_max = h_shell / font->getHeight(); list lines; - CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenY(), frameBuffer->getScreenWidth(), frameBuffer->getScreenHeight()); + CBox textBoxPosition(1, 1, w_shell, h_shell); textBox = new CTextBox(cmd.c_str(), font, CTextBox::BOTTOM, &textBoxPosition); struct pollfd fds; fds.fd = fileno(f); From 3896d7ceec82da722b1868e3eafcd639260fa360 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 28 Dec 2014 22:38:33 +0100 Subject: [PATCH 057/110] CShellWindow: add debug output for error ident --- src/gui/widget/shellwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index f42682d70..0acbf4728 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -195,6 +196,7 @@ void CShellWindow::exec() int r = waitpid(pid, &s, 0); if (res) { + dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] res=%d, error[%d]: %s\n", __func__, __LINE__, *res, errno, strerror(errno)); if (r == -1) *res = errno; else From f4bc1c8cb7ecf3b6046de5da4e1924fa2c30f1a5 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 21 Mar 2015 15:23:07 +0100 Subject: [PATCH 058/110] CShellWindow: reduce window size In some cases screen could be too small and some lines are cutted. --- src/gui/widget/shellwindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 0acbf4728..60ac40d73 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -85,11 +85,11 @@ void CShellWindow::exec() } Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]; - int h_shell = frameBuffer->getScreenHeight(true)-1; - int w_shell = frameBuffer->getScreenWidth(true)-1; + int h_shell = frameBuffer->getScreenHeight(); + int w_shell = frameBuffer->getScreenWidth(); unsigned int lines_max = h_shell / font->getHeight(); list lines; - CBox textBoxPosition(1, 1, w_shell, h_shell); + CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenX(), w_shell, h_shell); textBox = new CTextBox(cmd.c_str(), font, CTextBox::BOTTOM, &textBoxPosition); struct pollfd fds; fds.fd = fileno(f); From 7b178e71f9ebc00cd8d75075c11739097b579f72 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 25 Nov 2014 10:46:59 +0100 Subject: [PATCH 059/110] COPKGManager: add variable to hold last selected source dir --- src/gui/opkg_manager.cpp | 16 +++++++++------- src/gui/opkg_manager.h | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index d8ba77a38..d814f96be 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -90,6 +90,7 @@ COPKGManager::COPKGManager() list_installed_done = false; list_upgradeable_done = false; expert_mode = false; + local_dir = g_settings.update_dir.c_str(); CFileHelpers::createDir("/tmp/.opkg"); } @@ -144,14 +145,15 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) CFileBrowser fileBrowser; fileBrowser.Filter = &fileFilter; - if (fileBrowser.exec(g_settings.update_dir.c_str())) + if (fileBrowser.exec(local_dir.c_str())) { - string pgk_name = fileBrowser.getSelectedFile()->Name; - int r = execCmd(pkg_types[OM_INSTALL] + pgk_name, true, true); - if (r) { - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pgk_name); - } else - installed = true; + string pgk_name = fileBrowser.getSelectedFile()->Name; + int r = execCmd(pkg_types[OM_INSTALL] + pgk_name, true, true); + local_dir = fileBrowser.getCurrentDir(); + if (r) { + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pgk_name); + } else + installed = true; refreshMenu(); } return res; diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 46d7c8b74..7fac42452 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -57,6 +57,7 @@ class COPKGManager : public CMenuTarget bool installed; bool expert_mode; int menu_offset; + std::string local_dir; int execCmd(const char* cmdstr, bool verbose = false, bool acknowledge = false); int execCmd(std::string cmdstr, bool verbose = false, bool acknowledge = false) { From 5eff6a4fb9a4e5508bec4115f707bcb6a13fb1f3 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 25 Nov 2014 10:53:01 +0100 Subject: [PATCH 060/110] COPKGManager: add filter for ipk packages --- src/gui/opkg_manager.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index d814f96be..15556f180 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -139,8 +139,11 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) if (actionKey == "local_package") { if (parent) parent->hide(); + CFileFilter fileFilter; - fileFilter.addFilter("opk"); + string filters[] = {"opk", "ipk"}; + for(size_t i=0; i Date: Fri, 28 Nov 2014 09:19:38 +0100 Subject: [PATCH 061/110] COPKGManager: remember for last selected update directory Use g_settings to handle local package directory. Extra settings handler via gui for this directory is not intended. Default update directory is the same like in flash settings. --- src/gui/opkg_manager.cpp | 6 +++--- src/gui/opkg_manager.h | 2 +- src/neutrino.cpp | 4 ++++ src/system/settings.h | 5 ++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 15556f180..793e536ce 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -90,7 +90,7 @@ COPKGManager::COPKGManager() list_installed_done = false; list_upgradeable_done = false; expert_mode = false; - local_dir = g_settings.update_dir.c_str(); + local_dir = &g_settings.update_dir_opkg; CFileHelpers::createDir("/tmp/.opkg"); } @@ -148,11 +148,11 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) CFileBrowser fileBrowser; fileBrowser.Filter = &fileFilter; - if (fileBrowser.exec(local_dir.c_str())) + if (fileBrowser.exec((*local_dir).c_str())) { string pgk_name = fileBrowser.getSelectedFile()->Name; int r = execCmd(pkg_types[OM_INSTALL] + pgk_name, true, true); - local_dir = fileBrowser.getCurrentDir(); + *local_dir = fileBrowser.getCurrentDir(); if (r) { showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pgk_name); } else diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 7fac42452..c93fb5d38 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -57,7 +57,7 @@ class COPKGManager : public CMenuTarget bool installed; bool expert_mode; int menu_offset; - std::string local_dir; + std::string *local_dir; int execCmd(const char* cmdstr, bool verbose = false, bool acknowledge = false); int execCmd(std::string cmdstr, bool verbose = false, bool acknowledge = false) { diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 9d68da15e..385a36a70 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -766,7 +766,9 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.font_file = configfile.getString("font_file", FONTDIR"/neutrino.ttf"); g_settings.ttx_font_file = configfile.getString( "ttx_font_file", FONTDIR"/DejaVuLGCSansMono-Bold.ttf"); ttx_font_file = g_settings.ttx_font_file.c_str(); + g_settings.update_dir = configfile.getString("update_dir", "/tmp"); + g_settings.update_dir_opkg = configfile.getString("update_dir_opkg", g_settings.update_dir); // parentallock if (!parentallocked) { @@ -1239,6 +1241,8 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setString("softupdate_proxypassword" , g_settings.softupdate_proxypassword ); configfile.setString("update_dir", g_settings.update_dir); + configfile.setString("update_dir_opkg", g_settings.update_dir_opkg); + configfile.setString("font_file", g_settings.font_file); configfile.setString("ttx_font_file", g_settings.ttx_font_file); diff --git a/src/system/settings.h b/src/system/settings.h index 21a4d336d..c07a7428a 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -608,6 +608,9 @@ struct SNeutrinoSettings int flashupdate_createimage_add_spare; int flashupdate_createimage_add_kernel; + std::string update_dir; + std::string update_dir_opkg; + //BouquetHandling int bouquetlist_mode; @@ -725,7 +728,7 @@ struct SNeutrinoSettings int sms_channel; std::string font_file; std::string ttx_font_file; - std::string update_dir; + // USERMENU typedef enum { From dc3b6caae6486829734b04e1c43dbba357c44b8f Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 25 Nov 2014 11:06:26 +0100 Subject: [PATCH 062/110] COPKGManager: unified log output --- src/gui/opkg_manager.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 793e536ce..81b068d9f 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -288,7 +288,7 @@ bool COPKGManager::hasUpdates() for (map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++){ if (it->second.upgradable){ - dprintf(DEBUG_INFO, "[neutrino opkg] Update packages available...\n"); + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Update packages available...\n", __func__, __LINE__); ret = true; } } @@ -366,16 +366,15 @@ int COPKGManager::showMenu() bool COPKGManager::hasOpkgSupport() { - string deps[] = {"/etc/opkg/opkg.conf", "/var/lib/opkg", ""}; + string deps[] = {"/etc/opkg/opkg.conf", "/var/lib/opkg"}; if (find_executable(OPKG_CL).empty()) { - dprintf(DEBUG_INFO, "[neutrino opkg] did not find " OPKG_CL " executable\n"); + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d]" OPKG_CL " executable not found\n", __func__, __LINE__); return false; } - for (size_t i = 0; !deps[i].empty(); i++) { - dprintf(DEBUG_INFO, "[neutrino opkg] check if %s is available...\n", deps[i].c_str()); + for(size_t i=0; i Date: Sat, 29 Nov 2014 00:47:22 +0100 Subject: [PATCH 063/110] COPKGManager: add locales for local installation --- data/locale/deutsch.locale | 4 +++- data/locale/english.locale | 2 ++ data/locale/nederlands.locale | 2 ++ data/locale/slovak.locale | 1 + src/gui/opkg_manager.cpp | 3 ++- src/system/locals.h | 2 ++ src/system/locals_intern.h | 2 ++ 7 files changed, 14 insertions(+), 2 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 7a74eec2e..c78ddffca 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1195,7 +1195,8 @@ menu.hint_new_zap_mode Aktiviert Quickzap in der Kanalliste. Nach Betätigen der menu.hint_next Weiter zum nächsten Menü.\nDie Taste 'Menü' schließt alle Menüs menu.hint_next_brief Weiter zum nächsten Menü menu.hint_numeric_adjust Bei numerischer Programmwahl die Kanalliste am neu gewählten Programm ausrichten -menu.hint_opkg Hier können Sie neue Software-Pakete installieren oder vorhandene aktualisieren +menu.hint_opkg Software-Pakete installieren oder vorhandene aktualisieren +menu.hint_opkg_install_local_package Paket von USB-Stick, SD oder Freigabe installieren. menu.hint_opkg_upgrade Aktualisiert alle installierten Pakete auf die neueste verfügbare Version menu.hint_osd Farben, Schriftarten, Anzeigegröße, Ansichtsoptionen der Menüs und mehr menu.hint_osd_language Wählen Sie ihre Menü-Sprache @@ -1863,6 +1864,7 @@ opkg.button.uninstall Paket entfernen opkg.failure.install Installation fehlgeschlagen opkg.failure.update Update fehlgeschlagen opkg.failure.upgrade Upgrade fehlgeschlagen +opkg.install.local.package Installiere lokales Paket opkg.messagebox.reinstall %s erneut installieren? opkg.messagebox.remove %s entfernen? opkg.success.install Installation erfolgreich, Neustart von Neutrino kann erforderlich sein. diff --git a/data/locale/english.locale b/data/locale/english.locale index a6d844d6f..533c219b7 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1196,6 +1196,7 @@ menu.hint_next Continue to next menu\nPress menu key to close all menus menu.hint_next_brief Continue to next menu menu.hint_numeric_adjust Adjust channel list mode on numeric zap menu.hint_opkg Install or update software packages +menu.hint_opkg_install_local_package Install package from USB, SD or share. menu.hint_opkg_upgrade Updates all installed packages to the most recent version available menu.hint_osd Colors, fonts, screen size\nGUI look and feel options menu.hint_osd_language Select OSD language @@ -1863,6 +1864,7 @@ opkg.button.uninstall Uninstall package opkg.failure.install Install failed opkg.failure.update Update failed opkg.failure.upgrade Upgrade failed +opkg.install.local.package Install local package opkg.messagebox.reinstall Re-install %s? opkg.messagebox.remove Remove %s? opkg.success.install Install successful, restart of Neutrino might be required. diff --git a/data/locale/nederlands.locale b/data/locale/nederlands.locale index c113e5bc6..f9f3a8f70 100644 --- a/data/locale/nederlands.locale +++ b/data/locale/nederlands.locale @@ -1139,6 +1139,7 @@ menu.hint_network IP adres, gateway, DNS, Tijd synchronisatie\nNetwerklocaties e menu.hint_new_zap_mode Schakelen van kanalen toestaan tijdens het browsen.\n(Schakelen tussen vensters met de 'Mute' toets) menu.hint_numeric_adjust Pas zenderlijst modus aan na numerieke zap menu.hint_opkg Installeer of update software pakketten +menu.hint_opkg_install_local_package Installatiepakket van USB, SD of netwerk. menu.hint_opkg_upgrade Update alle geinstalleerde pakketten naar de meest recente beschikbare versie menu.hint_osd Kleuren, Lettertypes, scherm afmeting\ngebruikersinterface vormgeving menu.hint_osd_language Selecteer OSD taal @@ -1754,6 +1755,7 @@ opkg.button.uninstall Deinstaleer pakket opkg.failure.install installatie mislukt opkg.failure.update Update mislukt opkg.failure.upgrade Upgrade mislukt +opkg.install.local.package Installeer lokale pakket opkg.messagebox.reinstall Herinstalleer %s? opkg.messagebox.remove Wissen%s? opkg.success.install installatie succesvol, herstart van Neutrino mogelijk vereist. diff --git a/data/locale/slovak.locale b/data/locale/slovak.locale index 5dee3460b..05605d6a6 100644 --- a/data/locale/slovak.locale +++ b/data/locale/slovak.locale @@ -1845,6 +1845,7 @@ opkg.button.uninstall Odstrániť balíček opkg.failure.install inštalácia zlyhala opkg.failure.update aktualizácie zlyhala opkg.failure.upgrade Upgrade zlyhalo +opkg.install.local.package Nainštalujte miestne balíček opkg.messagebox.reinstall Preinštalovať %s? opkg.messagebox.remove Odstrániť %s? opkg.success.install Inštalácia v poriadku, reštart Neutrina bude žiadúci. diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 81b068d9f..a0e1aaa72 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -331,7 +331,8 @@ int COPKGManager::showMenu() //select and install local package CMenuForwarder *local; - local = new CMenuForwarder("Install Local Package" , true, NULL, this, "local_package", CRCInput::RC_green); + local = new CMenuForwarder(LOCALE_OPKG_INSTALL_LOCAL_PACKAGE, true, NULL, this, "local_package", CRCInput::RC_green); + local->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG_INSTALL_LOCAL_PACKAGE); menu->addItem(local); menu->addItem(GenericMenuSeparatorLine); diff --git a/src/system/locals.h b/src/system/locals.h index a7c2bdc67..17e9152ea 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1223,6 +1223,7 @@ typedef enum LOCALE_MENU_HINT_NEXT_BRIEF, LOCALE_MENU_HINT_NUMERIC_ADJUST, LOCALE_MENU_HINT_OPKG, + LOCALE_MENU_HINT_OPKG_INSTALL_LOCAL_PACKAGE, LOCALE_MENU_HINT_OPKG_UPGRADE, LOCALE_MENU_HINT_OSD, LOCALE_MENU_HINT_OSD_LANGUAGE, @@ -1890,6 +1891,7 @@ typedef enum LOCALE_OPKG_FAILURE_INSTALL, LOCALE_OPKG_FAILURE_UPDATE, LOCALE_OPKG_FAILURE_UPGRADE, + LOCALE_OPKG_INSTALL_LOCAL_PACKAGE, LOCALE_OPKG_MESSAGEBOX_REINSTALL, LOCALE_OPKG_MESSAGEBOX_REMOVE, LOCALE_OPKG_SUCCESS_INSTALL, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index edae0aee9..a0dc49897 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1223,6 +1223,7 @@ const char * locale_real_names[] = "menu.hint_next_brief", "menu.hint_numeric_adjust", "menu.hint_opkg", + "menu.hint_opkg_install_local_package", "menu.hint_opkg_upgrade", "menu.hint_osd", "menu.hint_osd_language", @@ -1890,6 +1891,7 @@ const char * locale_real_names[] = "opkg.failure.install", "opkg.failure.update", "opkg.failure.upgrade", + "opkg.install.local.package", "opkg.messagebox.reinstall", "opkg.messagebox.remove", "opkg.success.install", From f270a623e2aa62016b7b66c5dd624ae12dac9dbc Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Fri, 5 Dec 2014 20:35:10 +0100 Subject: [PATCH 064/110] COPKGManager: use yellow button instead red button in footer Red button already used for upgrades --- src/gui/opkg_manager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index a0e1aaa72..550f6eca5 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -131,7 +131,7 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) execCmd(pkg_types[OM_INFO] + pkg_vec[selected]->name, true, true); return res; } - if (actionKey == "rc_red") { + if (actionKey == "rc_yellow") { expert_mode = !expert_mode; updateMenu(); return res; @@ -199,13 +199,13 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) #define COPKGManagerFooterButtonCount 3 static const struct button_label COPKGManagerFooterButtons[COPKGManagerFooterButtonCount] = { - { NEUTRINO_ICON_BUTTON_RED, LOCALE_OPKG_BUTTON_EXPERT_ON }, + { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_OPKG_BUTTON_EXPERT_ON }, { NEUTRINO_ICON_BUTTON_INFO_SMALL, LOCALE_OPKG_BUTTON_INFO }, { NEUTRINO_ICON_BUTTON_OKAY, LOCALE_OPKG_BUTTON_INSTALL } }; #define COPKGManagerFooterButtonCountExpert 4 static const struct button_label COPKGManagerFooterButtonsExpert[COPKGManagerFooterButtonCountExpert] = { - { NEUTRINO_ICON_BUTTON_RED, LOCALE_OPKG_BUTTON_EXPERT_OFF }, + { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_OPKG_BUTTON_EXPERT_OFF }, { NEUTRINO_ICON_BUTTON_INFO_SMALL, LOCALE_OPKG_BUTTON_INFO }, { NEUTRINO_ICON_BUTTON_OKAY, LOCALE_OPKG_BUTTON_INSTALL }, { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_OPKG_BUTTON_UNINSTALL } @@ -341,7 +341,7 @@ int COPKGManager::showMenu() menu->addKey(CRCInput::RC_info, this, "rc_info"); menu->addKey(CRCInput::RC_blue, this, "rc_blue"); - menu->addKey(CRCInput::RC_red, this, "rc_red"); + menu->addKey(CRCInput::RC_yellow, this, "rc_yellow"); pkg_vec.clear(); for (map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++) { From c3f66e6e06bcc872637fdb70c0bbcc6ed58f9be3 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Fri, 22 May 2015 23:03:56 +0200 Subject: [PATCH 065/110] COPKGManager: fix selection of items on expert mode switch --- src/gui/opkg_manager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 550f6eca5..f94c59ce0 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -270,10 +270,13 @@ void COPKGManager::updateMenu() upgrade_forwarder->setActive(upgradesAvailable); - if (expert_mode) + if (expert_mode){ menu->setFooter(COPKGManagerFooterButtonsExpert, COPKGManagerFooterButtonCountExpert); - else + } + else{ + menu->setSelected(2); //back-item menu->setFooter(COPKGManagerFooterButtons, COPKGManagerFooterButtonCount); + } } bool COPKGManager::hasUpdates() From b3afd24260e87a7e722ad35a916edbafa8b7d91b Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Fri, 19 Dec 2014 21:08:25 +0100 Subject: [PATCH 066/110] COPKGManager: add members to get package infos and optmize update check --- data/locale/deutsch.locale | 1 + data/locale/english.locale | 1 + data/locale/nederlands.locale | 1 + data/locale/slovak.locale | 1 + src/gui/opkg_manager.cpp | 120 +++++++++++++++++++++++++++++----- src/gui/opkg_manager.h | 13 ++-- src/system/locals.h | 1 + src/system/locals_intern.h | 1 + 8 files changed, 116 insertions(+), 23 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index c78ddffca..015bff3db 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1867,6 +1867,7 @@ opkg.failure.upgrade Upgrade fehlgeschlagen opkg.install.local.package Installiere lokales Paket opkg.messagebox.reinstall %s erneut installieren? opkg.messagebox.remove %s entfernen? +opkg.messagebox.updates.available Aktualisierungen verfügbar! opkg.success.install Installation erfolgreich, Neustart von Neutrino kann erforderlich sein. opkg.title Paketverwaltung opkg.upgrade Installierte Pakete aktualisieren diff --git a/data/locale/english.locale b/data/locale/english.locale index 533c219b7..58195a60e 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1867,6 +1867,7 @@ opkg.failure.upgrade Upgrade failed opkg.install.local.package Install local package opkg.messagebox.reinstall Re-install %s? opkg.messagebox.remove Remove %s? +opkg.messagebox.updates.available Updates available! opkg.success.install Install successful, restart of Neutrino might be required. opkg.title Package Management opkg.upgrade Upgrade installed packages diff --git a/data/locale/nederlands.locale b/data/locale/nederlands.locale index f9f3a8f70..b14414176 100644 --- a/data/locale/nederlands.locale +++ b/data/locale/nederlands.locale @@ -1758,6 +1758,7 @@ opkg.failure.upgrade Upgrade mislukt opkg.install.local.package Installeer lokale pakket opkg.messagebox.reinstall Herinstalleer %s? opkg.messagebox.remove Wissen%s? +opkg.messagebox.updates.available Updates beschikbare! opkg.success.install installatie succesvol, herstart van Neutrino mogelijk vereist. opkg.title Pakket management opkg.upgrade Upgrade geïnstalleerd pakketten diff --git a/data/locale/slovak.locale b/data/locale/slovak.locale index 05605d6a6..2ae778458 100644 --- a/data/locale/slovak.locale +++ b/data/locale/slovak.locale @@ -1848,6 +1848,7 @@ opkg.failure.upgrade Upgrade zlyhalo opkg.install.local.package Nainštalujte miestne balíček opkg.messagebox.reinstall Preinštalovať %s? opkg.messagebox.remove Odstrániť %s? +opkg.messagebox.updates.available Aktualizácia k dispozícii! opkg.success.install Inštalácia v poriadku, reštart Neutrina bude žiadúci. opkg.title Správa balíčkov opkg.upgrade Aktualizovanie inštalovaných balíčkov diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index f94c59ce0..38eb3a9a6 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,7 @@ enum OM_REMOVE, OM_INFO, OM_INSTALL, + OM_STATUS, OM_MAX }; @@ -80,7 +82,8 @@ static const string pkg_types[OM_MAX] = OPKG_CL OPKG_CL_CONFIG_OPTIONS " upgrade ", OPKG_CL OPKG_CL_CONFIG_OPTIONS " remove ", OPKG_CL " info ", - OPKG_CL OPKG_CL_CONFIG_OPTIONS " install " + OPKG_CL OPKG_CL_CONFIG_OPTIONS " install ", + OPKG_CL " status ", }; COPKGManager::COPKGManager() @@ -188,10 +191,11 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) force = "--force-reinstall "; } int r = execCmd(pkg_types[OM_INSTALL] + force + actionKey, true, true); + DisplayInfoMessage(actionKey.c_str()); if (r) { showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + force + actionKey); } else - installed = true; + installed = true; refreshMenu(); } return res; @@ -279,24 +283,53 @@ void COPKGManager::updateMenu() } } -bool COPKGManager::hasUpdates() +bool COPKGManager::checkUpdates(const std::string & package_name, bool show_progress) { if (!hasOpkgSupport()) return false; + doUpdate(); + bool ret = false; getPkgData(OM_LIST); getPkgData(OM_LIST_UPGRADEABLE); + size_t i = 0; + CProgressWindow status; + status.showHeader(false); + + if (show_progress){ + status.paint(); + status.showStatus(i); + } + for (map::iterator it = pkg_map.begin(); it != pkg_map.end(); it++){ - if (it->second.upgradable){ - dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Update packages available...\n", __func__, __LINE__); - ret = true; + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Update check for...%s\n", __func__, __LINE__, it->second.name.c_str()); + if (show_progress){ + status.showStatusMessageUTF(it->second.name); + status.showStatus(100*i / pkg_map.size()); } + + if (it->second.upgradable){ + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Update packages available for...%s\n", __func__, __LINE__, it->second.name.c_str()); + if (!package_name.empty() && package_name == it->second.name){ + ret = true; + break; + }else + ret = true; + } + i++; + } + + if (show_progress){ + status.showGlobalStatus(100); + status.showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_READY)); // UTF-8 + status.hide(); } pkg_map.clear(); + return ret; } @@ -305,9 +338,9 @@ int COPKGManager::doUpdate() int r = execCmd(pkg_types[OM_UPDATE]); if (r == -1) { DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE)); -// showError(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE), strerror(errno), pkg_types[OM_UPDATE]); + return r; } - return r; + return 0; } void COPKGManager::refreshMenu() { @@ -319,7 +352,8 @@ void COPKGManager::refreshMenu() { int COPKGManager::showMenu() { installed = false; - doUpdate(); + if (checkUpdates()) + DisplayInfoMessage(g_Locale->getText(LOCALE_OPKG_MESSAGEBOX_UPDATES_AVAILABLE)); getPkgData(OM_LIST); getPkgData(OM_LIST_UPGRADEABLE); @@ -351,6 +385,7 @@ int COPKGManager::showMenu() if (badpackage(it->second.name)) continue; it->second.forwarder = new CMenuForwarder(it->second.desc, true, NULL , this, it->second.name.c_str()); + getPkgInfo(it->second.name, "Size"); it->second.forwarder->setHint("", it->second.desc); menu->addItem(it->second.forwarder); pkg_vec.push_back(&it->second); @@ -429,10 +464,12 @@ void COPKGManager::getPkgData(const int pkg_content_id) trim(line); string name = getBlankPkgName(line); + if (name.empty()) + continue; switch (pkg_content_id) { case OM_LIST: { - pkg_map[name] = pkg(name, line); + pkg_map[name] = pkg(name, line, line); break; } case OM_LIST_INSTALLED: { @@ -458,10 +495,48 @@ void COPKGManager::getPkgData(const int pkg_content_id) string COPKGManager::getBlankPkgName(const string& line) { - size_t l_pos = line.find(" "); - if (l_pos != string::npos) - return line.substr(0, l_pos); - return line; + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] line: %s\n", __func__, __LINE__, line.c_str()); + + //check for error relevant contents and return an empty string if found + size_t pos0 = line.find("Collected errors:"); + size_t pos01 = line.find(" * "); + if (pos0 != string::npos || pos01 != string::npos) + return ""; + + //split line and use name as return value + size_t pos1 = line.find(" "); + if (pos1 != string::npos) + return line.substr(0, pos1); + + return ""; +} + +string COPKGManager::getPkgInfo(const string& pkg_name, const string& pkg_key) +{ + tmp_str.clear(); + execCmd(pkg_types[OM_INFO] + pkg_name, false, true); + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] [data: %s]\n", __func__, __LINE__, tmp_str.c_str()); + + return getKeyInfo(tmp_str, pkg_key, ":"); +} + +string COPKGManager::getKeyInfo(const string& input, const std::string& key, const string& delimiters) +{ + string s = input; + size_t pos1 = s.find(key); + if (pos1 != string::npos){ + size_t pos2 = s.find(delimiters, pos1)+ delimiters.length(); + if (pos2 != string::npos){ + size_t pos3 = s.find("\n", pos2); + if (pos3 != string::npos){ + string ret = s.substr(pos2, pos3-pos2); + return trim(ret, " "); + } + else + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Error: [key: %s] missing end of line...\n", __func__, __LINE__, key.c_str()); + } + } + return ""; } int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) @@ -470,6 +545,7 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) string cmd = string(cmdstr); int res = 0; bool has_err = false; + tmp_str.clear(); string err_msg = ""; if (verbose) { // cmd += " 2>&1"; @@ -491,15 +567,23 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) //check for collected errors and build a message for screen if errors available if (has_err){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] %s \n", __func__, __LINE__, line.c_str()); - size_t pos1 = line.find(" * opkg_"); - string str = line.substr(pos1, line.length()-pos1); - err_msg += str.replace(pos1, 8,"") + "\n"; + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] cmd: %s\nresult: %s\n", __func__, __LINE__, cmd.c_str(), line.c_str()); + size_t pos1 = line.find(" * "); + if (pos1 != string::npos){ + string str = line.substr(pos1, line.length()-pos1); + err_msg += str.replace(pos1, 3,"") + "\n"; + } + size_t pos01 = line.find("wget returned 4"); + //find obvious errors + if (pos01 != string::npos) + err_msg = "Network error! Online update not possible."; }else{ size_t pos2 = line.find("Collected errors:"); if (pos2 != string::npos) has_err = true; } + if (!has_err) + tmp_str += line + "\n"; } fclose(f); } diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index c93fb5d38..edc7eef81 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -42,7 +42,7 @@ class COPKGManager : public CMenuTarget { private: int width; - + std::string tmp_str; CFrameBuffer *frameBuffer; struct pkg; @@ -64,7 +64,9 @@ class COPKGManager : public CMenuTarget return execCmd(cmdstr.c_str(), verbose, acknowledge); }; void getPkgData(const int pkg_content_id); - static std::string getBlankPkgName(const std::string& line); + std::string getBlankPkgName(const std::string& line); + std::string getPkgInfo(const std::string& pkg_name, const std::string& pkg_key); + std::string getKeyInfo(const std::string& input, const std::string& pkg_info_key, const std::string& delimiters); int showMenu(); void updateMenu(); void refreshMenu(); @@ -74,13 +76,14 @@ class COPKGManager : public CMenuTarget struct pkg { std::string name; + std::string version; std::string desc; bool installed; bool upgradable; CMenuForwarder *forwarder; pkg() { } - pkg(std::string &_name, std::string &_desc) - : name(_name), desc(_desc), installed(false), upgradable(false) { } + pkg(std::string &_name, std::string &_version, std::string &_desc) + : name(_name), version(_version), desc(_desc), installed(false), upgradable(false) { } }; public: COPKGManager(); @@ -88,6 +91,6 @@ class COPKGManager : public CMenuTarget int exec(CMenuTarget* parent, const std::string & actionKey); static bool hasOpkgSupport(); - bool hasUpdates(); + bool checkUpdates(const std::string & package_name = std::string(), bool show_progress = true); }; #endif diff --git a/src/system/locals.h b/src/system/locals.h index 17e9152ea..559fc58de 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1894,6 +1894,7 @@ typedef enum LOCALE_OPKG_INSTALL_LOCAL_PACKAGE, LOCALE_OPKG_MESSAGEBOX_REINSTALL, LOCALE_OPKG_MESSAGEBOX_REMOVE, + LOCALE_OPKG_MESSAGEBOX_UPDATES_AVAILABLE, LOCALE_OPKG_SUCCESS_INSTALL, LOCALE_OPKG_TITLE, LOCALE_OPKG_UPGRADE, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index a0dc49897..7fe25c9b0 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1894,6 +1894,7 @@ const char * locale_real_names[] = "opkg.install.local.package", "opkg.messagebox.reinstall", "opkg.messagebox.remove", + "opkg.messagebox.updates.available", "opkg.success.install", "opkg.title", "opkg.upgrade", From 4909844ad6f96d1de80302cf1f61addc83d2c0b8 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 10 Dec 2014 10:41:34 +0100 Subject: [PATCH 067/110] COPKGManager: add member to handle line of shell lines prepared for use as callback in shell window class, currently it is not possible to get line output from shellwindow object, this should help soon also added ne locales --- data/locale/deutsch.locale | 2 +- data/locale/english.locale | 2 +- src/gui/opkg_manager.cpp | 70 +++++++++++++++++++--------------- src/gui/opkg_manager.h | 4 ++ src/gui/widget/shellwindow.cpp | 9 ++++- src/gui/widget/shellwindow.h | 46 +++++++++++++++++----- 6 files changed, 90 insertions(+), 43 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 015bff3db..03e18de81 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1196,7 +1196,7 @@ menu.hint_next Weiter zum nächsten Menü.\nDie Taste 'Menü' schließt alle Men menu.hint_next_brief Weiter zum nächsten Menü menu.hint_numeric_adjust Bei numerischer Programmwahl die Kanalliste am neu gewählten Programm ausrichten menu.hint_opkg Software-Pakete installieren oder vorhandene aktualisieren -menu.hint_opkg_install_local_package Paket von USB-Stick, SD oder Freigabe installieren. +menu.hint_opkg_install_local_package Paket von USB-Stick, SD, Freigabe oder lokalem Ordner installieren. menu.hint_opkg_upgrade Aktualisiert alle installierten Pakete auf die neueste verfügbare Version menu.hint_osd Farben, Schriftarten, Anzeigegröße, Ansichtsoptionen der Menüs und mehr menu.hint_osd_language Wählen Sie ihre Menü-Sprache diff --git a/data/locale/english.locale b/data/locale/english.locale index 58195a60e..3e69ab85c 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1196,7 +1196,7 @@ menu.hint_next Continue to next menu\nPress menu key to close all menus menu.hint_next_brief Continue to next menu menu.hint_numeric_adjust Adjust channel list mode on numeric zap menu.hint_opkg Install or update software packages -menu.hint_opkg_install_local_package Install package from USB, SD or share. +menu.hint_opkg_install_local_package Install package from USB, SD, share or local directory. menu.hint_opkg_upgrade Updates all installed packages to the most recent version available menu.hint_osd Colors, fonts, screen size\nGUI look and feel options menu.hint_osd_language Select OSD language diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 38eb3a9a6..fc2407b95 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -191,7 +191,7 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) force = "--force-reinstall "; } int r = execCmd(pkg_types[OM_INSTALL] + force + actionKey, true, true); - DisplayInfoMessage(actionKey.c_str()); + if (r) { showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + force + actionKey); } else @@ -385,7 +385,6 @@ int COPKGManager::showMenu() if (badpackage(it->second.name)) continue; it->second.forwarder = new CMenuForwarder(it->second.desc, true, NULL , this, it->second.name.c_str()); - getPkgInfo(it->second.name, "Size"); it->second.forwarder->setHint("", it->second.desc); menu->addItem(it->second.forwarder); pkg_vec.push_back(&it->second); @@ -397,7 +396,7 @@ int COPKGManager::showMenu() menu->hide (); - if (installed) + if (!has_err && installed) DisplayInfoMessage(g_Locale->getText(LOCALE_OPKG_SUCCESS_INSTALL)); delete menu; return res; @@ -544,12 +543,15 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) fprintf(stderr, "execCmd(%s)\n", cmdstr); string cmd = string(cmdstr); int res = 0; - bool has_err = false; + has_err = false; tmp_str.clear(); - string err_msg = ""; + err_msg = ""; if (verbose) { -// cmd += " 2>&1"; - CShellWindow(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res); + sigc::slot1 sl; + sl = sigc::mem_fun(*this, &COPKGManager::handleShellOutput); + CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res, false); + shell.OnShellOutputLoop.connect(sl); + shell.exec(); } else { cmd += " 2>&1"; pid_t pid = 0; @@ -564,41 +566,49 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) string line(buf); trim(line); dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] %s [error %d]\n", __func__, __LINE__, line.c_str(), has_err); - - //check for collected errors and build a message for screen if errors available - if (has_err){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] cmd: %s\nresult: %s\n", __func__, __LINE__, cmd.c_str(), line.c_str()); - size_t pos1 = line.find(" * "); - if (pos1 != string::npos){ - string str = line.substr(pos1, line.length()-pos1); - err_msg += str.replace(pos1, 3,"") + "\n"; - } - size_t pos01 = line.find("wget returned 4"); - //find obvious errors - if (pos01 != string::npos) - err_msg = "Network error! Online update not possible."; - }else{ - size_t pos2 = line.find("Collected errors:"); - if (pos2 != string::npos) - has_err = true; - } - if (!has_err) - tmp_str += line + "\n"; + handleShellOutput(line); } fclose(f); } if (has_err){ - DisplayErrorMessage(err_msg.c_str()); +// if (!verbose) +// DisplayErrorMessage(err_msg.c_str()); return -1; } return res; } -void COPKGManager::showError(const char* local_msg, char* err_msg, const string& command) +void COPKGManager::handleShellOutput(string& cur_line) +{ + //check for collected errors and build a message for screen if errors available + if (has_err){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] result: %s\n", __func__, __LINE__, cur_line.c_str()); + size_t pos1 = cur_line.find(" * "); + if (pos1 != string::npos){ + string str = cur_line.substr(pos1, cur_line.length()-pos1); + err_msg += str.replace(pos1, 3,"") + "\n"; + } + + //find obvious errors + //download error: + size_t pos01 = cur_line.find("wget returned 4"); + if (pos01 != string::npos) + err_msg = "Network error! Online update not possible. Please check your network connection!\n"; + }else{ + size_t pos2 = cur_line.find("Collected errors:"); + if (pos2 != string::npos) + has_err = true; + } + if (!has_err) + tmp_str += cur_line + "\n"; +} + +void COPKGManager::showError(const char* local_msg, char* err_message, const string& command) { string msg = local_msg ? string(local_msg) + "\n" : ""; - msg += string(err_msg) + ":\n"; + msg += err_msg + "\n"; + msg += string(err_message) + ":\n"; msg += command; DisplayErrorMessage(msg.c_str()); } diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index edc7eef81..3c2298008 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -58,6 +58,9 @@ class COPKGManager : public CMenuTarget bool expert_mode; int menu_offset; std::string *local_dir; + + bool has_err; + std::string err_msg; int execCmd(const char* cmdstr, bool verbose = false, bool acknowledge = false); int execCmd(std::string cmdstr, bool verbose = false, bool acknowledge = false) { @@ -73,6 +76,7 @@ class COPKGManager : public CMenuTarget bool badpackage(std::string &s); void showError(const char* local_msg, char* err_msg, const std::string& command); int doUpdate(); + void handleShellOutput(std::string& cur_line); struct pkg { std::string name; diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 60ac40d73..d7e4c7f9a 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -46,7 +46,7 @@ #include #include -CShellWindow::CShellWindow(const std::string &Command, const int Mode, int *Res) +CShellWindow::CShellWindow(const std::string &Command, const int Mode, int *Res, bool auto_exec) { textBox = NULL; frameBuffer = CFrameBuffer::getInstance(); @@ -55,7 +55,8 @@ CShellWindow::CShellWindow(const std::string &Command, const int Mode, int *Res) mode = Mode; res = Res; - exec(); + if (auto_exec) + exec(); } void CShellWindow::exec() @@ -152,6 +153,10 @@ void CShellWindow::exec() lines.push_back(line); incomplete = true; } + + //callback for line handler + std::string s_output = std::string((output)); + OnShellOutputLoop(s_output); if (lines.size() > lines_max) lines.pop_front(); txt = ""; diff --git a/src/gui/widget/shellwindow.h b/src/gui/widget/shellwindow.h index 130c7f8ce..45d4cda84 100644 --- a/src/gui/widget/shellwindow.h +++ b/src/gui/widget/shellwindow.h @@ -32,9 +32,18 @@ #include #include +#include -class CShellWindow +class CShellWindow : public sigc::trackable { + private: + int mode; + std::string command; + int* res; + CFrameBuffer *frameBuffer; + CTextBox *textBox; + void showResult(); + public: enum shellwindow_modes { @@ -42,16 +51,35 @@ class CShellWindow ACKNOWLEDGE = 2, ACKNOWLEDGE_MSG = 4 }; - CShellWindow(const std::string &Command, const int Mode = 0, int* Res = NULL); + CShellWindow(const std::string &Command, const int Mode = 0, int* Res = NULL, bool auto_exec = true); ~CShellWindow(); - private: - int mode; - std::string command; - int* res; - CFrameBuffer *frameBuffer; - CTextBox *textBox; void exec(); - void showResult(); + + /*! + signal/event handler runs on loop in exec method + this allows to use the shell output lines in other objects eg. for evaluation of error or status data + example for implamentation in your class: + ...your code... + //assuming in your class is declared a member function named YourMemberFunction(std::string& arg), parameter is a string as rev: + //Tis function should handle the shell output! + + //declare a slot with return value as 'void' and parameter as 'string', here by rev! + sigc::slot1 sl; + + //fill the slot with your member function in your class that do evaluate the output lines + sl = sigc::mem_fun(*this, &CYourClass::YourMemberFunction); + + //create the CShellWindow object in verbose mode, important: parameter 'auto_exec' must be set to 'false', so it is possible to connect the slot before engages the exec() methode + CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res, false); + + //connect slot + shell.OnShellOutputLoop.connect(sl); + + //now exec... + shell.exec(); + ...other code... + */ + sigc::signal OnShellOutputLoop; }; #endif From a6f7043ab1147ac5dd5cf54d82e105c3090fab39 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 13 Dec 2014 00:03:27 +0100 Subject: [PATCH 068/110] COPKGManager: add possibilty to check required size before install package --- data/locale/deutsch.locale | 1 + data/locale/english.locale | 1 + data/locale/nederlands.locale | 1 + data/locale/slovak.locale | 1 + src/gui/opkg_manager.cpp | 38 +++++++++++++++++++++++++++++------ src/system/locals.h | 1 + src/system/locals_intern.h | 1 + 7 files changed, 38 insertions(+), 6 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 03e18de81..04dcbfb44 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1867,6 +1867,7 @@ opkg.failure.upgrade Upgrade fehlgeschlagen opkg.install.local.package Installiere lokales Paket opkg.messagebox.reinstall %s erneut installieren? opkg.messagebox.remove %s entfernen? +opkg.messagebox.size.error Nicht genügend freier Speicher für Paketinstallation verfügbar! opkg.messagebox.updates.available Aktualisierungen verfügbar! opkg.success.install Installation erfolgreich, Neustart von Neutrino kann erforderlich sein. opkg.title Paketverwaltung diff --git a/data/locale/english.locale b/data/locale/english.locale index 3e69ab85c..c44c45a55 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1867,6 +1867,7 @@ opkg.failure.upgrade Upgrade failed opkg.install.local.package Install local package opkg.messagebox.reinstall Re-install %s? opkg.messagebox.remove Remove %s? +opkg.messagebox.size.error Not enough free memory available for this package! opkg.messagebox.updates.available Updates available! opkg.success.install Install successful, restart of Neutrino might be required. opkg.title Package Management diff --git a/data/locale/nederlands.locale b/data/locale/nederlands.locale index b14414176..b367c67a8 100644 --- a/data/locale/nederlands.locale +++ b/data/locale/nederlands.locale @@ -1758,6 +1758,7 @@ opkg.failure.upgrade Upgrade mislukt opkg.install.local.package Installeer lokale pakket opkg.messagebox.reinstall Herinstalleer %s? opkg.messagebox.remove Wissen%s? +opkg.messagebox.size.error Onvoldoende geheugen beschikbaar voor dit pakket! opkg.messagebox.updates.available Updates beschikbare! opkg.success.install installatie succesvol, herstart van Neutrino mogelijk vereist. opkg.title Pakket management diff --git a/data/locale/slovak.locale b/data/locale/slovak.locale index 2ae778458..39f56a2f1 100644 --- a/data/locale/slovak.locale +++ b/data/locale/slovak.locale @@ -1848,6 +1848,7 @@ opkg.failure.upgrade Upgrade zlyhalo opkg.install.local.package Nainštalujte miestne balíček opkg.messagebox.reinstall Preinštalovať %s? opkg.messagebox.remove Odstrániť %s? +opkg.messagebox.size.error Nie je dostatok voľnej pamäte pre tento balík! opkg.messagebox.updates.available Aktualizácia k dispozícii! opkg.success.install Inštalácia v poriadku, reštart Neutrina bude žiadúci. opkg.title Správa balíčkov diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index fc2407b95..3044d8295 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -48,7 +48,7 @@ #include #include #include - +#include #include #include #include @@ -190,12 +190,38 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) return res; force = "--force-reinstall "; } - int r = execCmd(pkg_types[OM_INSTALL] + force + actionKey, true, true); - if (r) { - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + force + actionKey); - } else - installed = true; + //get package size + string s_pkgsize = getPkgInfo(actionKey, "Size"); + std::istringstream s(s_pkgsize); + u_int64_t pkg_size; + s >> pkg_size; + + //get available size + //TODO: Check writability! + struct statfs root_fs; + statfs("/",&root_fs); + u_int64_t free_size = root_fs.f_bfree*root_fs.f_bsize; + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [package size=%lld (free size: %lld)]\n", __func__, __LINE__, actionKey.c_str(), pkg_size, free_size); + + //only for sure, it's more secure for users to abort installation if is available size too small + //TODO: Package size is not really the same like required/recommended size, because of unknown compression factor, some possible options like cache, different tmp-dir size eg. are still not considered. + u_int64_t rec_size = pkg_size/2*3; + if (free_size < rec_size){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld required size=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, pkg_size, rec_size); + DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_MESSAGEBOX_SIZE_ERROR)); + }else{ + string cmd = pkg_types[OM_INSTALL] + force + actionKey; + int r = execCmd(cmd, true, true); + string cur_version = getPkgInfo(actionKey, "Version"); + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] %s: current version = %s\n", __func__, __LINE__, actionKey.c_str(), cur_version.c_str()); + if (r){ + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), cmd); + }else{ + installed = true; + } + } + refreshMenu(); } return res; diff --git a/src/system/locals.h b/src/system/locals.h index 559fc58de..3b2d2c74e 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1894,6 +1894,7 @@ typedef enum LOCALE_OPKG_INSTALL_LOCAL_PACKAGE, LOCALE_OPKG_MESSAGEBOX_REINSTALL, LOCALE_OPKG_MESSAGEBOX_REMOVE, + LOCALE_OPKG_MESSAGEBOX_SIZE_ERROR, LOCALE_OPKG_MESSAGEBOX_UPDATES_AVAILABLE, LOCALE_OPKG_SUCCESS_INSTALL, LOCALE_OPKG_TITLE, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 7fe25c9b0..e1a2c2de0 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1894,6 +1894,7 @@ const char * locale_real_names[] = "opkg.install.local.package", "opkg.messagebox.reinstall", "opkg.messagebox.remove", + "opkg.messagebox.size.error", "opkg.messagebox.updates.available", "opkg.success.install", "opkg.title", From 7acdf65e6504880125957b6c274224df31732bd4 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Fri, 19 Dec 2014 22:09:04 +0100 Subject: [PATCH 069/110] COPKGManager: defuse error message for duplicate cache option --- src/gui/opkg_manager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 3044d8295..ec3a2375f 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -621,6 +621,11 @@ void COPKGManager::handleShellOutput(string& cur_line) size_t pos01 = cur_line.find("wget returned 4"); if (pos01 != string::npos) err_msg = "Network error! Online update not possible. Please check your network connection!\n"; + + //duplicate option cache: option is defined in OPKG_CL_CONFIG_OPTIONS, NOTE: if found first cache option in the opkg.conf file, this will be preferred + pos01 = cur_line.find("Duplicate option cache"); + if (pos01 != string::npos) + has_err = false; }else{ size_t pos2 = cur_line.find("Collected errors:"); if (pos2 != string::npos) From 10debbbfa0f6141e4cd87d9a180b56fe0da12c65 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Fri, 19 Dec 2014 23:33:05 +0100 Subject: [PATCH 070/110] COPKGManager: optimize handling after installation Show a success message only if restart/reboot is required and user should decide what to do or not. NOTE: marker file should be generated by opkg package itself (eg. with preinstall scripts), so it's controlled by the package maintainer! --- data/locale/deutsch.locale | 2 +- data/locale/english.locale | 2 +- data/locale/nederlands.locale | 2 +- data/locale/slovak.locale | 2 +- src/gui/opkg_manager.cpp | 31 +++++++++++++++++++++++++++++-- 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 04dcbfb44..064460f5e 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1869,7 +1869,7 @@ opkg.messagebox.reinstall %s erneut installieren? opkg.messagebox.remove %s entfernen? opkg.messagebox.size.error Nicht genügend freier Speicher für Paketinstallation verfügbar! opkg.messagebox.updates.available Aktualisierungen verfügbar! -opkg.success.install Installation erfolgreich, Neustart von Neutrino kann erforderlich sein. +opkg.success.install Installation erfolgreich!\nNeustart von Neutrino kann erforderlich sein. Jetzt neu starten? opkg.title Paketverwaltung opkg.upgrade Installierte Pakete aktualisieren options.default Voreinstellungen benutzen diff --git a/data/locale/english.locale b/data/locale/english.locale index c44c45a55..ddf07ed69 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1869,7 +1869,7 @@ opkg.messagebox.reinstall Re-install %s? opkg.messagebox.remove Remove %s? opkg.messagebox.size.error Not enough free memory available for this package! opkg.messagebox.updates.available Updates available! -opkg.success.install Install successful, restart of Neutrino might be required. +opkg.success.install Install successful!\n restart of Neutrino might be required. Restart now? opkg.title Package Management opkg.upgrade Upgrade installed packages options.default Reset to defaults diff --git a/data/locale/nederlands.locale b/data/locale/nederlands.locale index b367c67a8..2c8198f88 100644 --- a/data/locale/nederlands.locale +++ b/data/locale/nederlands.locale @@ -1760,7 +1760,7 @@ opkg.messagebox.reinstall Herinstalleer %s? opkg.messagebox.remove Wissen%s? opkg.messagebox.size.error Onvoldoende geheugen beschikbaar voor dit pakket! opkg.messagebox.updates.available Updates beschikbare! -opkg.success.install installatie succesvol, herstart van Neutrino mogelijk vereist. +opkg.success.install installatie succesvol!\n herstart van Neutrino mogelijk vereist. Nu opnieuw opstarten? opkg.title Pakket management opkg.upgrade Upgrade geïnstalleerd pakketten options.default Herstel standaardwaarden diff --git a/data/locale/slovak.locale b/data/locale/slovak.locale index 39f56a2f1..1259d1480 100644 --- a/data/locale/slovak.locale +++ b/data/locale/slovak.locale @@ -1850,7 +1850,7 @@ opkg.messagebox.reinstall Preinštalovať %s? opkg.messagebox.remove Odstrániť %s? opkg.messagebox.size.error Nie je dostatok voľnej pamäte pre tento balík! opkg.messagebox.updates.available Aktualizácia k dispozícii! -opkg.success.install Inštalácia v poriadku, reštart Neutrina bude žiadúci. +opkg.success.install inštalácia úspešne!\n Môže byť potrebné reštart neutríno. Teraz reštartovať? opkg.title Správa balíčkov opkg.upgrade Aktualizovanie inštalovaných balíčkov options.default obnov predvolené diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index ec3a2375f..bc9de4384 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -422,9 +422,36 @@ int COPKGManager::showMenu() menu->hide (); - if (!has_err && installed) - DisplayInfoMessage(g_Locale->getText(LOCALE_OPKG_SUCCESS_INSTALL)); + //handling after successful installation + string exit_action = ""; + if (!has_err && installed){ + /*! + Show a success message only if restart/reboot is required and user should decide what to do or not. + NOTE: marker file should be generated by opkg package itself (eg. with preinstall scripts), + so it's controlled by the package maintainer! + */ + //restart neutrino: user decision + if(!access( "/tmp/.restart", F_OK)){ + int msg = ShowMsg(LOCALE_OPKG_TITLE, g_Locale->getText(LOCALE_OPKG_SUCCESS_INSTALL), CMsgBox::mbrNo, + CMsgBox::mbYesNo, + NEUTRINO_ICON_QUESTION, + width); + if (msg == CMsgBox::mbrYes) + exit_action = "restart"; + } + //restart neutrino: forced + if (!access( "/tmp/.force_restart", F_OK)) + exit_action = "restart"; + //reboot stb: forced + if (!access( "/tmp/.reboot", F_OK)) + exit_action = "reboot"; + } + delete menu; + + if (!exit_action.empty()) + CNeutrinoApp::getInstance()->exec(NULL, exit_action); + return res; } From 7520fee2ef691e1013168cb3f988baf0e72843d3 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 20 Dec 2014 21:04:35 +0100 Subject: [PATCH 071/110] COPKGManager: outsource methode for install any package Required for external usage. --- src/gui/opkg_manager.cpp | 23 +++++++++++++++++------ src/gui/opkg_manager.h | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index bc9de4384..1476ec05e 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -153,13 +153,10 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) if (fileBrowser.exec((*local_dir).c_str())) { - string pgk_name = fileBrowser.getSelectedFile()->Name; - int r = execCmd(pkg_types[OM_INSTALL] + pgk_name, true, true); + string pkg_name = fileBrowser.getSelectedFile()->Name; + installPackage(pkg_name); + *local_dir = fileBrowser.getCurrentDir(); - if (r) { - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pgk_name); - } else - installed = true; refreshMenu(); } return res; @@ -670,3 +667,17 @@ void COPKGManager::showError(const char* local_msg, char* err_message, const str msg += command; DisplayErrorMessage(msg.c_str()); } + +bool COPKGManager::installPackage(const std::string& pkg_name) +{ + int r = execCmd(pkg_types[OM_INSTALL] + pkg_name, true, true); + + if (r){ + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_name); + return false; + } + else + installed = true; + + return true; +} diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 3c2298008..3e1c2cf0b 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -96,5 +96,6 @@ class COPKGManager : public CMenuTarget int exec(CMenuTarget* parent, const std::string & actionKey); static bool hasOpkgSupport(); bool checkUpdates(const std::string & package_name = std::string(), bool show_progress = true); + bool installPackage(const std::string& pkg_name); }; #endif From 7ada20de641b4c5be824ab764239e5c36753ff81 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 21 Dec 2014 00:32:30 +0100 Subject: [PATCH 072/110] CFile: add filetypes for install and update packages --- src/driver/file.cpp | 16 ++++++++-------- src/driver/file.h | 4 +++- src/gui/opkg_manager.cpp | 6 +++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/driver/file.cpp b/src/driver/file.cpp index 0d16b37bb..ce4c809f5 100644 --- a/src/driver/file.cpp +++ b/src/driver/file.cpp @@ -42,21 +42,21 @@ /* ATTENTION: the array file_extension_list MUST BE SORTED ASCENDING (cf. sort, man bsearch) - otherwise bsearch will not work correctly! */ const char * const file_extension_list[] = { - "aac", "asf", "avi", "bmp", "cdr", "crw", - "dts", "flac", "flv", "gif", "imu", "iso", "jpeg", "jpg", + "aac", "asf", "avi", "bin", "bmp", "cdr", "crw", + "dts", "flac", "flv", "gif", "imu", "ipk", "iso", "jpeg", "jpg", "m2a", "m3u", "m3u8", "m4a", "mkv", "mp2", "mp3", - "mpa", "ogg", "pls", "png", "sh", + "mpa", "ogg", "opk", "pls", "png", "sh", "txt", "url", "wav", "xml" }; /* ATTENTION: the array file_extension_list MUST BE SORTED ASCENDING (cf. sort, man bsearch) - otherwise bsearch will not work correctly! */ const CFile::FileType file_type_list[] = { - CFile::FILE_AAC , CFile::FILE_ASF , CFile::FILE_AVI , CFile::FILE_PICTURE , CFile::FILE_CDR , CFile::FILE_PICTURE , - CFile::FILE_WAV , CFile::FILE_FLAC , CFile::FILE_FLV , CFile::FILE_PICTURE , CFile::STREAM_PICTURE, CFile::FILE_ISO , CFile::FILE_PICTURE , CFile::FILE_PICTURE , - CFile::FILE_MP3 , CFile::FILE_PLAYLIST , CFile::FILE_PLAYLIST , CFile::FILE_AAC , CFile::FILE_MKV , CFile::FILE_MP3 , CFile::FILE_MP3 , - CFile::FILE_MP3 , CFile::FILE_OGG , CFile::FILE_PLAYLIST , CFile::FILE_PICTURE , CFile::FILE_TEXT , - CFile::FILE_TEXT , CFile::STREAM_AUDIO , CFile::FILE_WAV , CFile::FILE_XML + CFile::FILE_AAC , CFile::FILE_ASF , CFile::FILE_AVI , CFile::FILE_BIN_PACKAGE ,CFile::FILE_PICTURE , CFile::FILE_CDR , CFile::FILE_PICTURE , + CFile::FILE_WAV , CFile::FILE_FLAC , CFile::FILE_FLV , CFile::FILE_PICTURE , CFile::STREAM_PICTURE , CFile::FILE_PKG_PACKAGE ,CFile::FILE_ISO , CFile::FILE_PICTURE , CFile::FILE_PICTURE , + CFile::FILE_MP3 , CFile::FILE_PLAYLIST , CFile::FILE_PLAYLIST , CFile::FILE_AAC , CFile::FILE_MKV , CFile::FILE_MP3 , CFile::FILE_MP3 , + CFile::FILE_MP3 , CFile::FILE_OGG , CFile::FILE_PKG_PACKAGE, CFile::FILE_PLAYLIST , CFile::FILE_PICTURE , CFile::FILE_TEXT , + CFile::FILE_TEXT , CFile::STREAM_AUDIO , CFile::FILE_WAV , CFile::FILE_XML }; int mycasecmp(const void * a, const void * b) diff --git a/src/driver/file.h b/src/driver/file.h index 987886d29..b26e52475 100644 --- a/src/driver/file.h +++ b/src/driver/file.h @@ -71,7 +71,9 @@ class CFile FILE_PLAYLIST, STREAM_AUDIO, FILE_PICTURE, - STREAM_PICTURE + STREAM_PICTURE, + FILE_BIN_PACKAGE, + FILE_PKG_PACKAGE }; FileType getType(void) const; diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 1476ec05e..192d5116b 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -429,11 +429,11 @@ int COPKGManager::showMenu() */ //restart neutrino: user decision if(!access( "/tmp/.restart", F_OK)){ - int msg = ShowMsg(LOCALE_OPKG_TITLE, g_Locale->getText(LOCALE_OPKG_SUCCESS_INSTALL), CMsgBox::mbrNo, - CMsgBox::mbYesNo, + int msg = ShowMsg(LOCALE_OPKG_TITLE, g_Locale->getText(LOCALE_OPKG_SUCCESS_INSTALL), CMessageBox::mbrNo, + CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_QUESTION, width); - if (msg == CMsgBox::mbrYes) + if (msg == CMessageBox::mbrYes) exit_action = "restart"; } //restart neutrino: forced From 33bf0fd7baa5365aa34d0fac3abe6aaed06b641b Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 21 Dec 2014 20:41:41 +0100 Subject: [PATCH 073/110] Locales: add message line for not supported feature --- data/locale/deutsch.locale | 2 ++ data/locale/english.locale | 3 +++ data/locale/nederlands.locale | 2 ++ data/locale/slovak.locale | 2 ++ src/system/locals.h | 2 ++ src/system/locals_intern.h | 2 ++ 6 files changed, 13 insertions(+) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 064460f5e..346cc95d1 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1432,6 +1432,7 @@ messagebox.back Zurück messagebox.cancel Abbruch messagebox.discard Wollen Sie die Änderungen verwerfen? messagebox.error Fehler +messagebox.feature_not_supported Funktion wird nicht unterstützt. Bitte wenden Sie sich an Ihren Firmware-Anbieter! messagebox.info Information messagebox.no Nein messagebox.ok OK @@ -1872,6 +1873,7 @@ opkg.messagebox.updates.available Aktualisierungen verfügbar! opkg.success.install Installation erfolgreich!\nNeustart von Neutrino kann erforderlich sein. Jetzt neu starten? opkg.title Paketverwaltung opkg.upgrade Installierte Pakete aktualisieren +opkg.warning_3rdparty_packages Drittanbieter-Pakete könnten Ihr System beschädigen! Sind Sie sicher, dieses Paket zu installieren? options.default Voreinstellungen benutzen options.fb framebuffer options.hint_default Setzen Sie die Werte auf die Voreinstellung zurück. diff --git a/data/locale/english.locale b/data/locale/english.locale index ddf07ed69..e009e21f5 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1432,6 +1432,8 @@ messagebox.back Back messagebox.cancel Cancel messagebox.discard Discard changes? messagebox.error Error +messagebox.feature_not_supported Funkcia nie je podporovaná. +messagebox.feature_not_supported Feature is not supported. Please contact your firmware provider! messagebox.info Information messagebox.no No messagebox.ok Ok @@ -1872,6 +1874,7 @@ opkg.messagebox.updates.available Updates available! opkg.success.install Install successful!\n restart of Neutrino might be required. Restart now? opkg.title Package Management opkg.upgrade Upgrade installed packages +opkg.warning_3rdparty_packages 3rd party packages could damage your system! Are you sure install this package? options.default Reset to defaults options.fb framebuffer options.hint_default Reset the values to their defaults diff --git a/data/locale/nederlands.locale b/data/locale/nederlands.locale index 2c8198f88..73a4d6ba1 100644 --- a/data/locale/nederlands.locale +++ b/data/locale/nederlands.locale @@ -1364,6 +1364,7 @@ messagebox.back Terug messagebox.cancel Annuleer messagebox.discard Wijzigingen ongedaan maken? messagebox.error Foutmelding +messagebox.feature_not_supported Functie wordt niet ondersteund. Neem contact op met uw firmware provider! messagebox.info Informatie messagebox.no Nee messagebox.ok Ok @@ -1763,6 +1764,7 @@ opkg.messagebox.updates.available Updates beschikbare! opkg.success.install installatie succesvol!\n herstart van Neutrino mogelijk vereist. Nu opnieuw opstarten? opkg.title Pakket management opkg.upgrade Upgrade geïnstalleerd pakketten +opkg.warning_3rdparty_packages 3rd party pakketten kan uw systeem beschadigen! Bent u zeker dat dit pakket te installeren? options.default Herstel standaardwaarden options.fb framebuffer options.hint_default Reset de waardes naar standaard waardes diff --git a/data/locale/slovak.locale b/data/locale/slovak.locale index 1259d1480..9469975cd 100644 --- a/data/locale/slovak.locale +++ b/data/locale/slovak.locale @@ -1423,6 +1423,7 @@ messagebox.back späť messagebox.cancel zruš messagebox.discard Zruš zmeny? messagebox.error Chyba +messagebox.feature_not_supported Funkcia nie je podporovaná! messagebox.info Správa messagebox.no nie messagebox.ok ok @@ -1853,6 +1854,7 @@ opkg.messagebox.updates.available Aktualizácia k dispozícii! opkg.success.install inštalácia úspešne!\n Môže byť potrebné reštart neutríno. Teraz reštartovať? opkg.title Správa balíčkov opkg.upgrade Aktualizovanie inštalovaných balíčkov +opkg.warning_3rdparty_packages Zahraničné balíčky by mohli poškodiť systém! Si si istý, že inštaláciu tohto balíka? options.default obnov predvolené options.fb FRAMEBUFFER options.hint_default Nastaviť prednastavené hodnoty diff --git a/src/system/locals.h b/src/system/locals.h index 3b2d2c74e..764f1fb7d 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1459,6 +1459,7 @@ typedef enum LOCALE_MESSAGEBOX_CANCEL, LOCALE_MESSAGEBOX_DISCARD, LOCALE_MESSAGEBOX_ERROR, + LOCALE_MESSAGEBOX_FEATURE_NOT_SUPPORTED, LOCALE_MESSAGEBOX_INFO, LOCALE_MESSAGEBOX_NO, LOCALE_MESSAGEBOX_OK, @@ -1899,6 +1900,7 @@ typedef enum LOCALE_OPKG_SUCCESS_INSTALL, LOCALE_OPKG_TITLE, LOCALE_OPKG_UPGRADE, + LOCALE_OPKG_WARNING_3RDPARTY_PACKAGES, LOCALE_OPTIONS_DEFAULT, LOCALE_OPTIONS_FB, LOCALE_OPTIONS_HINT_DEFAULT, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index e1a2c2de0..ac1b17d74 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1459,6 +1459,7 @@ const char * locale_real_names[] = "messagebox.cancel", "messagebox.discard", "messagebox.error", + "messagebox.feature_not_supported", "messagebox.info", "messagebox.no", "messagebox.ok", @@ -1899,6 +1900,7 @@ const char * locale_real_names[] = "opkg.success.install", "opkg.title", "opkg.upgrade", + "opkg.warning_3rdparty_packages", "options.default", "options.fb", "options.hint_default", From 9ae65d4ec5c10c08dd2bd4cc58cf4fde569dcadd Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 28 Dec 2014 20:14:33 +0100 Subject: [PATCH 074/110] COPKGManager: add function to check package size --- src/gui/opkg_manager.cpp | 61 ++++++++++++++++++++++------------------ src/gui/opkg_manager.h | 1 + 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 192d5116b..a871705ef 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -188,35 +188,16 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) force = "--force-reinstall "; } - //get package size - string s_pkgsize = getPkgInfo(actionKey, "Size"); - std::istringstream s(s_pkgsize); - u_int64_t pkg_size; - s >> pkg_size; - - //get available size - //TODO: Check writability! - struct statfs root_fs; - statfs("/",&root_fs); - u_int64_t free_size = root_fs.f_bfree*root_fs.f_bsize; - dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [package size=%lld (free size: %lld)]\n", __func__, __LINE__, actionKey.c_str(), pkg_size, free_size); - - //only for sure, it's more secure for users to abort installation if is available size too small - //TODO: Package size is not really the same like required/recommended size, because of unknown compression factor, some possible options like cache, different tmp-dir size eg. are still not considered. - u_int64_t rec_size = pkg_size/2*3; - if (free_size < rec_size){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld required size=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, pkg_size, rec_size); + //check package size...cancel installation if size check failed + if (!checkSize(actionKey)){ DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_MESSAGEBOX_SIZE_ERROR)); - }else{ - string cmd = pkg_types[OM_INSTALL] + force + actionKey; - int r = execCmd(cmd, true, true); - string cur_version = getPkgInfo(actionKey, "Version"); - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] %s: current version = %s\n", __func__, __LINE__, actionKey.c_str(), cur_version.c_str()); - if (r){ - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), cmd); - }else{ + } + else{ + int r = execCmd(pkg_types[OM_INSTALL] + force + actionKey, true, true); + if (r) + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + force + actionKey); + else installed = true; - } } refreshMenu(); @@ -224,6 +205,32 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) return res; } +bool COPKGManager::checkSize(const string& pkg_name) +{ + //get package size + string s_pkgsize = getPkgInfo(pkg_name, "Size"); + std::istringstream s(s_pkgsize); + u_int64_t pkg_size; + s >> pkg_size; + + //get available size + //TODO: Check writability! + struct statfs root_fs; + statfs("/",&root_fs); + u_int64_t free_size = root_fs.f_bfree*root_fs.f_bsize; + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [package size=%lld (free size: %lld)]\n", __func__, __LINE__, pkg_name.c_str(), pkg_size, free_size); + + //only for sure, it's more secure for users to abort installation if is available size too small + //TODO: Package size is not really the same like required/recommended size, because of unknown compression factor, some possible options like cache, different tmp-dir size eg. are still not considered. + u_int64_t rec_size = pkg_size/2*3; + if (free_size < rec_size){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld required size=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, pkg_size, rec_size); + return false; + } + return true; +} + + #define COPKGManagerFooterButtonCount 3 static const struct button_label COPKGManagerFooterButtons[COPKGManagerFooterButtonCount] = { { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_OPKG_BUTTON_EXPERT_ON }, diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 3e1c2cf0b..45a5fee32 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -97,5 +97,6 @@ class COPKGManager : public CMenuTarget static bool hasOpkgSupport(); bool checkUpdates(const std::string & package_name = std::string(), bool show_progress = true); bool installPackage(const std::string& pkg_name); + bool checkSize(const std::string& pkg_name); }; #endif From 9a4863173a3397572a654b53675973611b768fcc Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 28 Dec 2014 20:39:25 +0100 Subject: [PATCH 075/110] COPKGManager: add more error handlers --- src/gui/opkg_manager.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index a871705ef..414853516 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -154,7 +154,8 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) if (fileBrowser.exec((*local_dir).c_str())) { string pkg_name = fileBrowser.getSelectedFile()->Name; - installPackage(pkg_name); + if (!installPackage(pkg_name)) + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_name); *local_dir = fileBrowser.getCurrentDir(); refreshMenu(); @@ -641,22 +642,25 @@ void COPKGManager::handleShellOutput(string& cur_line) //check for collected errors and build a message for screen if errors available if (has_err){ dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] result: %s\n", __func__, __LINE__, cur_line.c_str()); + size_t pos1 = cur_line.find(" * "); - if (pos1 != string::npos){ + + //trivial errors: + //duplicate option cache: option is defined in OPKG_CL_CONFIG_OPTIONS, NOTE: if found first cache option in the opkg.conf file, this will be preferred + if (cur_line.find("Duplicate option cache") != string::npos){ + has_err = true; + } + else if (pos1 != string::npos){ string str = cur_line.substr(pos1, cur_line.length()-pos1); err_msg += str.replace(pos1, 3,"") + "\n"; + has_err = true; } - //find obvious errors //download error: - size_t pos01 = cur_line.find("wget returned 4"); - if (pos01 != string::npos) + else if (cur_line.find("wget returned 4") != string::npos){ err_msg = "Network error! Online update not possible. Please check your network connection!\n"; - - //duplicate option cache: option is defined in OPKG_CL_CONFIG_OPTIONS, NOTE: if found first cache option in the opkg.conf file, this will be preferred - pos01 = cur_line.find("Duplicate option cache"); - if (pos01 != string::npos) - has_err = false; + has_err = true; + } }else{ size_t pos2 = cur_line.find("Collected errors:"); if (pos2 != string::npos) @@ -680,7 +684,7 @@ bool COPKGManager::installPackage(const std::string& pkg_name) int r = execCmd(pkg_types[OM_INSTALL] + pkg_name, true, true); if (r){ - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_name); +// showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_name); return false; } else From 19dc7ead2dfb7df56f1d27967d7f069c240e45f1 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 29 Dec 2014 00:21:49 +0100 Subject: [PATCH 076/110] COPKGManager: optimize error handling --- src/gui/opkg_manager.cpp | 48 ++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 414853516..af3785697 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -629,8 +629,6 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) fclose(f); } if (has_err){ -// if (!verbose) -// DisplayErrorMessage(err_msg.c_str()); return -1; } @@ -639,32 +637,49 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) void COPKGManager::handleShellOutput(string& cur_line) { + size_t pos2 = cur_line.find("Collected errors:"); + if (pos2 != string::npos) + has_err = true; + //check for collected errors and build a message for screen if errors available if (has_err){ dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] result: %s\n", __func__, __LINE__, cur_line.c_str()); - size_t pos1 = cur_line.find(" * "); - //trivial errors: - //duplicate option cache: option is defined in OPKG_CL_CONFIG_OPTIONS, NOTE: if found first cache option in the opkg.conf file, this will be preferred + /*duplicate option cache: option is defined in OPKG_CL_CONFIG_OPTIONS, + * NOTE: if found first cache option in the opkg.conf file, this will be preferred and it's not really an error! + */ if (cur_line.find("Duplicate option cache") != string::npos){ - has_err = true; - } - else if (pos1 != string::npos){ - string str = cur_line.substr(pos1, cur_line.length()-pos1); - err_msg += str.replace(pos1, 3,"") + "\n"; - has_err = true; + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: Duplicate option cache, please check opkg config file!\n", __func__, __LINE__); + has_err = false; } + //find obvious errors //download error: - else if (cur_line.find("wget returned 4") != string::npos){ - err_msg = "Network error! Online update not possible. Please check your network connection!\n"; + if (cur_line.find("opkg_download:") != string::npos){ + err_msg += "Network error! Please check your network connection!\n"; has_err = true; } - }else{ - size_t pos2 = cur_line.find("Collected errors:"); - if (pos2 != string::npos) + //install errors: + if (cur_line.find("opkg_install_pkg") != string::npos){ + err_msg += "Update not possible!\n"; has_err = true; + } + if (cur_line.find("opkg_install_cmd") != string::npos){ + err_msg += "Cannot install package!\n"; + has_err = true; + } + if (has_err) + return; + + //add unknown errors: + size_t pos1 = cur_line.find(" * "); + if (pos1 != string::npos){ + string str = cur_line.substr(pos1, cur_line.length()-pos1); + err_msg += str.replace(pos1, 3,"") + "\n"; + return; + } + } if (!has_err) tmp_str += cur_line + "\n"; @@ -684,6 +699,7 @@ bool COPKGManager::installPackage(const std::string& pkg_name) int r = execCmd(pkg_types[OM_INSTALL] + pkg_name, true, true); if (r){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] error[%d]: %s\n", __func__, __LINE__, errno, strerror(errno)); // showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_name); return false; } From 68585f1a0dc1cb7e8cdfc2226efc0214f0b4a8be Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 20 Dec 2014 23:37:41 +0100 Subject: [PATCH 077/110] CFlashUpdate: add filters for packages --- src/gui/update.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/update.cpp b/src/gui/update.cpp index 7664dc950..11dd16758 100644 --- a/src/gui/update.cpp +++ b/src/gui/update.cpp @@ -410,8 +410,10 @@ printf("[update] mode is %d\n", softupdate_mode); CFileFilter UpdatesFilter; if(allow_flash) UpdatesFilter.addFilter(FILEBROWSER_UPDATE_FILTER); - UpdatesFilter.addFilter("bin"); - UpdatesFilter.addFilter("txt"); + + string filters[] = {"bin", "txt", "opk", "ipk"}; + for(size_t i=0; i Date: Sat, 20 Dec 2014 23:39:45 +0100 Subject: [PATCH 078/110] CFlashUpdate: add log output for not found package file --- src/gui/update.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/update.cpp b/src/gui/update.cpp index 11dd16758..a3f5e91b8 100644 --- a/src/gui/update.cpp +++ b/src/gui/update.cpp @@ -435,7 +435,7 @@ printf("[update] mode is %d\n", softupdate_mode); fclose(fd); else { hide(); - printf("flash-file not found: %s\n", filename.c_str()); + printf("flash/package-file not found: %s\n", filename.c_str()); ShowHint(LOCALE_MESSAGEBOX_ERROR, g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENFILE)); // UTF-8 return false; } From 9ff051249619e4a6241f0e3138b3d07027b583fe Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 20 Dec 2014 23:43:00 +0100 Subject: [PATCH 079/110] CFlashUpdate: change lines for better statement readability --- src/gui/update.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gui/update.cpp b/src/gui/update.cpp index a3f5e91b8..c760ec88c 100644 --- a/src/gui/update.cpp +++ b/src/gui/update.cpp @@ -440,13 +440,18 @@ printf("[update] mode is %d\n", softupdate_mode); return false; } hide(); + //set internal filetype char const * ptr = rindex(filename.c_str(), '.'); if(ptr) { ptr++; - if(!strcmp(ptr, "bin")) fileType = 'A'; - else if(!strcmp(ptr, "txt")) fileType = 'T'; - else if(!allow_flash) return false; - else fileType = 0; + if(!strcmp(ptr, "bin")) + fileType = 'A'; + else if(!strcmp(ptr, "txt")) + fileType = 'T'; + else if(!allow_flash) + return false; + else + fileType = 0; #ifdef DEBUG printf("[update] manual file type: %s %c\n", ptr, fileType); #endif From 58fa104967be93dc06d32f7f92bdb1766c522f69 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 21 Dec 2014 00:13:23 +0100 Subject: [PATCH 080/110] CFlashUpdate: add localized messages for installation from default update feature --- src/gui/update.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/gui/update.cpp b/src/gui/update.cpp index c760ec88c..e221756a1 100644 --- a/src/gui/update.cpp +++ b/src/gui/update.cpp @@ -48,7 +48,7 @@ #include #include - +#include #include #include @@ -436,10 +436,23 @@ printf("[update] mode is %d\n", softupdate_mode); else { hide(); printf("flash/package-file not found: %s\n", filename.c_str()); - ShowHint(LOCALE_MESSAGEBOX_ERROR, g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENFILE)); // UTF-8 + DisplayErrorMessage(g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENFILE)); return false; } hide(); + + //package install: + if (file_selected->getType() == CFile::FILE_PKG_PACKAGE){ + COPKGManager opkg; + if (opkg.hasOpkgSupport()){ + int msgres = ShowMsg(LOCALE_MESSAGEBOX_INFO, "Start installation?", CMessageBox::mbrYes, CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_UPDATE, 700); // UTF-8 + if (msgres == CMessageBox::mbrYes){ + if (!opkg.installPackage(UpdatesBrowser.getSelectedFile()->Name)) + DisplayErrorMessage("Installation failed!"); + } + } + return false; + } //set internal filetype char const * ptr = rindex(filename.c_str(), '.'); if(ptr) { From 936735a77ff09a690b878127f136c729c60d387f Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 21 Dec 2014 15:47:28 +0100 Subject: [PATCH 081/110] CSoftwareUpdate: show package feature as disabled without support --- src/gui/update_menue.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/gui/update_menue.cpp b/src/gui/update_menue.cpp index 68c075cf4..5c54266fe 100644 --- a/src/gui/update_menue.cpp +++ b/src/gui/update_menue.cpp @@ -106,12 +106,9 @@ int CSoftwareUpdate::showSoftwareUpdate() softUpdate.addItem(mf); //firmware update via opkg - if (COPKGManager::hasOpkgSupport()) { - mf = new CMenuForwarder(LOCALE_OPKG_TITLE, true, NULL, new COPKGManager()); - mf->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG); - softUpdate.addItem(mf); - } - + mf = new CMenuForwarder(LOCALE_OPKG_TITLE, COPKGManager::hasOpkgSupport(), NULL, new COPKGManager()); + mf->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG); + softUpdate.addItem(mf); } #ifdef BOXMODEL_APOLLO From 362018ed766a13a9487e179ab630b7ab59657c1d Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 28 Dec 2014 20:42:16 +0100 Subject: [PATCH 082/110] CFlashUpdate: use locales for install and error messages --- src/gui/update.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/update.cpp b/src/gui/update.cpp index e221756a1..83346a471 100644 --- a/src/gui/update.cpp +++ b/src/gui/update.cpp @@ -445,12 +445,15 @@ printf("[update] mode is %d\n", softupdate_mode); if (file_selected->getType() == CFile::FILE_PKG_PACKAGE){ COPKGManager opkg; if (opkg.hasOpkgSupport()){ - int msgres = ShowMsg(LOCALE_MESSAGEBOX_INFO, "Start installation?", CMessageBox::mbrYes, CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_UPDATE, 700); // UTF-8 + int msgres = ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_OPKG_WARNING_3RDPARTY_PACKAGES, CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_UPDATE, 700); // UTF-8 if (msgres == CMessageBox::mbrYes){ if (!opkg.installPackage(UpdatesBrowser.getSelectedFile()->Name)) - DisplayErrorMessage("Installation failed!"); + DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL)); } } + else + DisplayInfoMessage(g_Locale->getText(LOCALE_MESSAGEBOX_FEATURE_NOT_SUPPORTED)); + //!always leave here! return false; } //set internal filetype From 28d17802d400f3e4b8c95b6e4db629f677e486d6 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 30 Dec 2014 21:18:44 +0100 Subject: [PATCH 083/110] COPKGManager: show message on space error --- src/gui/opkg_manager.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index af3785697..9483712f3 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -368,7 +368,8 @@ int COPKGManager::doUpdate() { int r = execCmd(pkg_types[OM_UPDATE]); if (r == -1) { - DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE)); + string msg = string(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE)) + "\n" + err_msg; + DisplayErrorMessage(msg.c_str()); return r; } return 0; @@ -669,6 +670,10 @@ void COPKGManager::handleShellOutput(string& cur_line) err_msg += "Cannot install package!\n"; has_err = true; } + if (cur_line.find("No space left on device") != string::npos){ + err_msg += "Not enough space available!\n"; + has_err = true; + } if (has_err) return; @@ -677,9 +682,10 @@ void COPKGManager::handleShellOutput(string& cur_line) if (pos1 != string::npos){ string str = cur_line.substr(pos1, cur_line.length()-pos1); err_msg += str.replace(pos1, 3,"") + "\n"; - return; + has_err = true; } - + if (has_err) + return; } if (!has_err) tmp_str += cur_line + "\n"; From 2ca1648070287cbe780bacb2d7ffc49f9b3596e9 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 30 Dec 2014 23:08:40 +0100 Subject: [PATCH 084/110] COPKGManager: optimize memory check before install --- src/gui/opkg_manager.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 9483712f3..47cb74d97 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -219,13 +219,17 @@ bool COPKGManager::checkSize(const string& pkg_name) struct statfs root_fs; statfs("/",&root_fs); u_int64_t free_size = root_fs.f_bfree*root_fs.f_bsize; - dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [package size=%lld (free size: %lld)]\n", __func__, __LINE__, pkg_name.c_str(), pkg_size, free_size); - //only for sure, it's more secure for users to abort installation if is available size too small - //TODO: Package size is not really the same like required/recommended size, because of unknown compression factor, some possible options like cache, different tmp-dir size eg. are still not considered. - u_int64_t rec_size = pkg_size/2*3; - if (free_size < rec_size){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld required size=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, pkg_size, rec_size); + /* + * FIXME: Package size is not really the same like required/recommended size, because of unknown compression factor of package, possible options like cache, different tmp-dir size, + * size of required dependencies eg. are still not considered. + * Experience values are nearly to factor 2.1 to 2.5 related to package size. That's generously but not 100% sure! + */ + float pkg_raw_size = float(pkg_size); + u_int64_t req_size = u_int64_t(pkg_raw_size*2.5); + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [required size=%lld (free size: %lld)]\n", __func__, __LINE__, pkg_name.c_str(), req_size, free_size); + if (free_size < req_size){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld package size=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, pkg_size, req_size); return false; } return true; From 55a027efbf318d371ede4ac1e9ff977844060583 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 4 Feb 2015 11:17:16 +0100 Subject: [PATCH 085/110] COPKGManager: add methodes to get infos and status of packages --- src/gui/opkg_manager.cpp | 13 +++++++++---- src/gui/opkg_manager.h | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 47cb74d97..36afb9e5f 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -209,11 +209,14 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) bool COPKGManager::checkSize(const string& pkg_name) { //get package size - string s_pkgsize = getPkgInfo(pkg_name, "Size"); + string s_pkgsize = getPkgInfo(pkg_name, "Size", false); std::istringstream s(s_pkgsize); u_int64_t pkg_size; s >> pkg_size; + string status = getPkgInfo(pkg_name, "Status"); + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] Status of %s: %s\n", __func__, __LINE__, pkg_name.c_str(), status.c_str()); + //get available size //TODO: Check writability! struct statfs root_fs; @@ -230,7 +233,9 @@ bool COPKGManager::checkSize(const string& pkg_name) dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [required size=%lld (free size: %lld)]\n", __func__, __LINE__, pkg_name.c_str(), req_size, free_size); if (free_size < req_size){ dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld package size=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, pkg_size, req_size); - return false; + //exit with false if package not installed, allready installed packages will be be removed before install, therefore it should be enough disk space available +// if (status.empty()) + return false; } return true; } @@ -573,10 +578,10 @@ string COPKGManager::getBlankPkgName(const string& line) return ""; } -string COPKGManager::getPkgInfo(const string& pkg_name, const string& pkg_key) +string COPKGManager::getPkgInfo(const string& pkg_name, const string& pkg_key, bool current_status) { tmp_str.clear(); - execCmd(pkg_types[OM_INFO] + pkg_name, false, true); + execCmd(pkg_types[current_status ? OM_STATUS : OM_INFO] + pkg_name, false, true); dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] [data: %s]\n", __func__, __LINE__, tmp_str.c_str()); return getKeyInfo(tmp_str, pkg_key, ":"); diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 45a5fee32..91d053bc7 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -68,7 +68,20 @@ class COPKGManager : public CMenuTarget }; void getPkgData(const int pkg_content_id); std::string getBlankPkgName(const std::string& line); - std::string getPkgInfo(const std::string& pkg_name, const std::string& pkg_key); + + /* + * Gets an info from opkg command info or status from a package via keywords as std::string + * 1st parameter is name of package as string eg. "gdb", without file extension or version data + * 2nd parameter needs a keyword like: + * Package, Version, Depends, Status, Section, Architecture, Maintainer, MD5Sum, Size, Filename, Source, Description + * These kewords are to find in the control package inside of the opkg package file and the package list. + * 3rd parameter sets the sub command status or info. For more details, take a look to the opkg commands via command line. + */ + std::string getPkgInfo(const std::string& pkg_name, const std::string& pkg_key, bool current_status = false); + + //Does the same like getPkgInfo(), but only for status + std::string getPkgStatus(const std::string& pkg_name, const std::string& pkg_key){return getPkgInfo(pkg_name, pkg_key, true);} + std::string getKeyInfo(const std::string& input, const std::string& pkg_info_key, const std::string& delimiters); int showMenu(); void updateMenu(); From 14d21fdeec5392efb10b65331195418222252f10 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 31 Jan 2015 21:55:01 +0100 Subject: [PATCH 086/110] COPKGManager: use installPackage() for install from package list too installPackage() has also a new parameter for options, in this case is --force-reinstall in use. --- src/gui/opkg_manager.cpp | 37 ++++++++++++++++--------------------- src/gui/opkg_manager.h | 2 +- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 36afb9e5f..1a966e4cf 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -5,7 +5,7 @@ OPKG-Manager Class for Neutrino-GUI Implementation: - Copyright (C) 2012-2014 T. Graf 'dbt' + Copyright (C) 2012-2015 T. Graf 'dbt' www.dbox2-tuning.net Adaptions: @@ -189,17 +189,8 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) force = "--force-reinstall "; } - //check package size...cancel installation if size check failed - if (!checkSize(actionKey)){ - DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_MESSAGEBOX_SIZE_ERROR)); - } - else{ - int r = execCmd(pkg_types[OM_INSTALL] + force + actionKey, true, true); - if (r) - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + force + actionKey); - else - installed = true; - } + //install package with size check ...cancel installation if check failed + installPackage(actionKey, force); refreshMenu(); } @@ -709,17 +700,21 @@ void COPKGManager::showError(const char* local_msg, char* err_message, const str DisplayErrorMessage(msg.c_str()); } -bool COPKGManager::installPackage(const std::string& pkg_name) +bool COPKGManager::installPackage(const string& pkg_name, string options) { - int r = execCmd(pkg_types[OM_INSTALL] + pkg_name, true, true); - - if (r){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] error[%d]: %s\n", __func__, __LINE__, errno, strerror(errno)); -// showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_name); - return false; + //check package size...cancel installation if size check failed + if (!checkSize(pkg_name)){ + DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_MESSAGEBOX_SIZE_ERROR)); + } + else{ + string opts = " " + options + " "; + + int r = execCmd(pkg_types[OM_INSTALL] + opts + pkg_name, true, true); + if (r) + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + opts + pkg_name); + else + installed = true; } - else - installed = true; return true; } diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 91d053bc7..3a659f6ca 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -109,7 +109,7 @@ class COPKGManager : public CMenuTarget int exec(CMenuTarget* parent, const std::string & actionKey); static bool hasOpkgSupport(); bool checkUpdates(const std::string & package_name = std::string(), bool show_progress = true); - bool installPackage(const std::string& pkg_name); + bool installPackage(const std::string& pkg_name, std::string options = std::string()); bool checkSize(const std::string& pkg_name); }; #endif From ee56b7556721908774f5971eff7ebda0b0ec465d Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 31 Jan 2015 22:52:41 +0100 Subject: [PATCH 087/110] COPKGManager: ensure cleanup /tmp/.opkg after closing packet manager --- src/gui/opkg_manager.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 1a966e4cf..70a3b575c 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -56,6 +56,7 @@ /* later this can be changed to just "opkg" */ #define OPKG_CL "opkg-cl" #define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=/tmp/.opkg " +#define OPKG_TMP_DIR "/tmp/.opkg" using namespace std; @@ -94,11 +95,12 @@ COPKGManager::COPKGManager() list_upgradeable_done = false; expert_mode = false; local_dir = &g_settings.update_dir_opkg; - CFileHelpers::createDir("/tmp/.opkg"); + CFileHelpers::createDir(OPKG_TMP_DIR); } COPKGManager::~COPKGManager() { + CFileHelpers::removeDir(OPKG_TMP_DIR); } int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) @@ -108,7 +110,9 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) if (actionKey.empty()) { if (parent) parent->hide(); - return showMenu(); + int ret = showMenu(); + CFileHelpers::removeDir(OPKG_TMP_DIR); + return ret; } int selected = menu->getSelected() - menu_offset; From aad5db705f8a1de3633f8f86a7170f2272974dbd Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 4 Feb 2015 11:12:18 +0100 Subject: [PATCH 088/110] COPKGManager: add possibility to manage source feeds for packages Feeds are saved in opkg config file. NOTE:Existing config file will be overwrite, so must be reconfigured via gui. Source names are strictly numbered src 0...10 (maximmal 10 at the moment) FIXME: input mask in keyboardinput class is too small for some adresses, large address names are cutted and makes entries useless --- data/locale/deutsch.locale | 4 ++ data/locale/english.locale | 4 ++ data/locale/nederlands.locale | 4 ++ src/gui/opkg_manager.cpp | 98 ++++++++++++++++++++++++++++++++--- src/gui/opkg_manager.h | 15 ++++-- src/system/locals.h | 4 ++ src/system/locals_intern.h | 4 ++ 7 files changed, 123 insertions(+), 10 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 346cc95d1..a7e8a5e8c 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1196,6 +1196,7 @@ menu.hint_next Weiter zum nächsten Menü.\nDie Taste 'Menü' schließt alle Men menu.hint_next_brief Weiter zum nächsten Menü menu.hint_numeric_adjust Bei numerischer Programmwahl die Kanalliste am neu gewählten Programm ausrichten menu.hint_opkg Software-Pakete installieren oder vorhandene aktualisieren +menu.hint_opkg_feed_address_edit Bearbeiten von Feed-Adressen menu.hint_opkg_install_local_package Paket von USB-Stick, SD, Freigabe oder lokalem Ordner installieren. menu.hint_opkg_upgrade Aktualisiert alle installierten Pakete auf die neueste verfügbare Version menu.hint_osd Farben, Schriftarten, Anzeigegröße, Ansichtsoptionen der Menüs und mehr @@ -1862,9 +1863,12 @@ opkg.button.expert_on Experten-Modus opkg.button.info Paket-Informationen opkg.button.install Paket installieren opkg.button.uninstall Paket entfernen +opkg.enter.feed.address Bitte Adresse für Server-Feed oder lokalen Ordner eintragen! +opkg.enter.feed.address.example Beispiel: http://pkg.nevis.neutrino-hd.com opkg.failure.install Installation fehlgeschlagen opkg.failure.update Update fehlgeschlagen opkg.failure.upgrade Upgrade fehlgeschlagen +opkg.feed.addresses Feed-Adressen opkg.install.local.package Installiere lokales Paket opkg.messagebox.reinstall %s erneut installieren? opkg.messagebox.remove %s entfernen? diff --git a/data/locale/english.locale b/data/locale/english.locale index e009e21f5..504a3aa17 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1196,6 +1196,7 @@ menu.hint_next Continue to next menu\nPress menu key to close all menus menu.hint_next_brief Continue to next menu menu.hint_numeric_adjust Adjust channel list mode on numeric zap menu.hint_opkg Install or update software packages +menu.hint_opkg_feed_address_edit Edit feed addresses menu.hint_opkg_install_local_package Install package from USB, SD, share or local directory. menu.hint_opkg_upgrade Updates all installed packages to the most recent version available menu.hint_osd Colors, fonts, screen size\nGUI look and feel options @@ -1863,9 +1864,12 @@ opkg.button.expert_on Expert mode opkg.button.info Package information opkg.button.install Install package opkg.button.uninstall Uninstall package +opkg.enter.feed.address Please enter address for server, local folder or share! +opkg.enter.feed.address.example Example: http://pkg.nevis.neutrino-hd.com opkg.failure.install Install failed opkg.failure.update Update failed opkg.failure.upgrade Upgrade failed +opkg.feed.addresses Feed addresses opkg.install.local.package Install local package opkg.messagebox.reinstall Re-install %s? opkg.messagebox.remove Remove %s? diff --git a/data/locale/nederlands.locale b/data/locale/nederlands.locale index 73a4d6ba1..3ba931bec 100644 --- a/data/locale/nederlands.locale +++ b/data/locale/nederlands.locale @@ -1139,6 +1139,7 @@ menu.hint_network IP adres, gateway, DNS, Tijd synchronisatie\nNetwerklocaties e menu.hint_new_zap_mode Schakelen van kanalen toestaan tijdens het browsen.\n(Schakelen tussen vensters met de 'Mute' toets) menu.hint_numeric_adjust Pas zenderlijst modus aan na numerieke zap menu.hint_opkg Installeer of update software pakketten +menu.hint_opkg_feed_address_edit Bewerk server adressen! menu.hint_opkg_install_local_package Installatiepakket van USB, SD of netwerk. menu.hint_opkg_upgrade Update alle geinstalleerde pakketten naar de meest recente beschikbare versie menu.hint_osd Kleuren, Lettertypes, scherm afmeting\ngebruikersinterface vormgeving @@ -1753,9 +1754,12 @@ opkg.button.expert_on Expert modus opkg.button.info Pakket info opkg.button.install Installeer pakket opkg.button.uninstall Deinstaleer pakket +opkg.enter.feed.address Voer het adres van de server! +opkg.enter.feed.address.example Voorbeeld: http://pkg.nevis.neutrino-hd.com opkg.failure.install installatie mislukt opkg.failure.update Update mislukt opkg.failure.upgrade Upgrade mislukt +opkg.feed.addresses Feed adressen opkg.install.local.package Installeer lokale pakket opkg.messagebox.reinstall Herinstalleer %s? opkg.messagebox.remove Wissen%s? diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 70a3b575c..71b6ef3cb 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -55,8 +56,11 @@ #include /* later this can be changed to just "opkg" */ #define OPKG_CL "opkg-cl" -#define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=/tmp/.opkg " #define OPKG_TMP_DIR "/tmp/.opkg" +#define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=" OPKG_TMP_DIR + + +#define OPKG_CONFIG_FILE "/etc/opkg/opkg.conf" using namespace std; @@ -87,15 +91,23 @@ static const string pkg_types[OM_MAX] = OPKG_CL " status ", }; -COPKGManager::COPKGManager() +COPKGManager::COPKGManager(): opkg_conf('\t') { width = 80; + + //define default dest keys + string dest_defaults[] = {"/", OPKG_TMP_DIR, "/mnt"}; + for(size_t i=0; ihide(); int ret = showMenu(); + saveConfig(); CFileHelpers::removeDir(OPKG_TMP_DIR); return ret; } @@ -403,10 +416,17 @@ int COPKGManager::showMenu() menu->addItem(upgrade_forwarder); //select and install local package - CMenuForwarder *local; - local = new CMenuForwarder(LOCALE_OPKG_INSTALL_LOCAL_PACKAGE, true, NULL, this, "local_package", CRCInput::RC_green); - local->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG_INSTALL_LOCAL_PACKAGE); - menu->addItem(local); + CMenuForwarder *fw; + fw = new CMenuForwarder(LOCALE_OPKG_INSTALL_LOCAL_PACKAGE, true, NULL, this, "local_package", CRCInput::RC_green); + fw->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG_INSTALL_LOCAL_PACKAGE); + menu->addItem(fw); + + //feed setup + CMenuWidget feeds_menu(LOCALE_OPKG_TITLE, NEUTRINO_ICON_UPDATE, w_max (100, 10)); + showMenuConfigFeed(&feeds_menu); + fw = new CMenuForwarder(LOCALE_OPKG_FEED_ADRESSES, true, NULL, &feeds_menu, NULL, CRCInput::RC_www); + fw->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, LOCALE_MENU_HINT_OPKG_FEED_ADRESSES_EDIT); + menu->addItem(fw); menu->addItem(GenericMenuSeparatorLine); @@ -467,7 +487,7 @@ int COPKGManager::showMenu() bool COPKGManager::hasOpkgSupport() { - string deps[] = {"/etc/opkg/opkg.conf", "/var/lib/opkg"}; + string deps[] = {"/bin/opkg-check-config", "/bin/update-alternatives", "/var/lib/opkg", "/share/opkg/intercept"}; if (find_executable(OPKG_CL).empty()) { dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d]" OPKG_CL " executable not found\n", __func__, __LINE__); @@ -722,3 +742,67 @@ bool COPKGManager::installPackage(const string& pkg_name, string options) return true; } + + +void COPKGManager::showMenuConfigFeed(CMenuWidget *feed_menu) +{ + feed_menu->addIntroItems(LOCALE_OPKG_FEED_ADRESSES); + + for(size_t i=0; iaddItem( fw); + } +} + +void COPKGManager::loadConfig() +{ + opkg_conf.clear(); + bool load_defaults = false; + + if (!opkg_conf.loadConfig(OPKG_CONFIG_FILE, '\t')){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] Error: error while loading opkg config file! -> %s. Using default settings!\n", __func__, __LINE__, OPKG_CONFIG_FILE); + load_defaults = true; + } + + //package feeds + for(size_t i=0; i %s\n", __func__, __LINE__, OPKG_CONFIG_FILE); + DisplayErrorMessage("Error while saving opkg config file!"); + } +} diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 3a659f6ca..338a3d160 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -5,7 +5,7 @@ OPKG-Manager Class for Neutrino-GUI Implementation: - Copyright (C) 2012 T. Graf 'dbt' + Copyright (C) 2012-2015 T. Graf 'dbt' www.dbox2-tuning.net Adaptions: @@ -33,20 +33,28 @@ #include #include - +#include #include #include #include +#define OPKG_MAX_FEEDS 10 + class COPKGManager : public CMenuTarget { private: int width; std::string tmp_str; CFrameBuffer *frameBuffer; - + CConfigFile opkg_conf; + void saveConfig(); + void loadConfig(); struct pkg; + //config + std::string config_src[OPKG_MAX_FEEDS]; + std::vector config_dest; + std::map pkg_map; std::vector pkg_vec; @@ -84,6 +92,7 @@ class COPKGManager : public CMenuTarget std::string getKeyInfo(const std::string& input, const std::string& pkg_info_key, const std::string& delimiters); int showMenu(); + void showMenuConfigFeed(CMenuWidget *feed_menu); void updateMenu(); void refreshMenu(); bool badpackage(std::string &s); diff --git a/src/system/locals.h b/src/system/locals.h index 764f1fb7d..9a9bcdb21 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1223,6 +1223,7 @@ typedef enum LOCALE_MENU_HINT_NEXT_BRIEF, LOCALE_MENU_HINT_NUMERIC_ADJUST, LOCALE_MENU_HINT_OPKG, + LOCALE_MENU_HINT_OPKG_FEED_ADRESSES_EDIT, LOCALE_MENU_HINT_OPKG_INSTALL_LOCAL_PACKAGE, LOCALE_MENU_HINT_OPKG_UPGRADE, LOCALE_MENU_HINT_OSD, @@ -1889,9 +1890,12 @@ typedef enum LOCALE_OPKG_BUTTON_INFO, LOCALE_OPKG_BUTTON_INSTALL, LOCALE_OPKG_BUTTON_UNINSTALL, + LOCALE_OPKG_ENTER_FEED_ADDRESS, + LOCALE_OPKG_ENTER_FEED_ADDRESS_EXAMPLE, LOCALE_OPKG_FAILURE_INSTALL, LOCALE_OPKG_FAILURE_UPDATE, LOCALE_OPKG_FAILURE_UPGRADE, + LOCALE_OPKG_FEED_ADRESSES, LOCALE_OPKG_INSTALL_LOCAL_PACKAGE, LOCALE_OPKG_MESSAGEBOX_REINSTALL, LOCALE_OPKG_MESSAGEBOX_REMOVE, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index ac1b17d74..a34fd0d00 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1223,6 +1223,7 @@ const char * locale_real_names[] = "menu.hint_next_brief", "menu.hint_numeric_adjust", "menu.hint_opkg", + "menu.hint_opkg_feed_address_edit", "menu.hint_opkg_install_local_package", "menu.hint_opkg_upgrade", "menu.hint_osd", @@ -1889,9 +1890,12 @@ const char * locale_real_names[] = "opkg.button.info", "opkg.button.install", "opkg.button.uninstall", + "opkg.enter.feed.address", + "opkg.enter.feed.address.example", "opkg.failure.install", "opkg.failure.update", "opkg.failure.upgrade", + "opkg.feed.addresses", "opkg.install.local.package", "opkg.messagebox.reinstall", "opkg.messagebox.remove", From 0f1a6e7588a6368159c737af8f7f647873e0f0ce Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 5 Feb 2015 12:26:29 +0100 Subject: [PATCH 089/110] COPKGManager: add optional parameter force_configure to installPackage() --- src/gui/opkg_manager.cpp | 11 ++++++++--- src/gui/opkg_manager.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 71b6ef3cb..629b3f021 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -75,6 +75,7 @@ enum OM_INFO, OM_INSTALL, OM_STATUS, + OM_CONFIGURE, OM_MAX }; @@ -89,6 +90,7 @@ static const string pkg_types[OM_MAX] = OPKG_CL " info ", OPKG_CL OPKG_CL_CONFIG_OPTIONS " install ", OPKG_CL " status ", + OPKG_CL " configure " }; COPKGManager::COPKGManager(): opkg_conf('\t') @@ -724,7 +726,7 @@ void COPKGManager::showError(const char* local_msg, char* err_message, const str DisplayErrorMessage(msg.c_str()); } -bool COPKGManager::installPackage(const string& pkg_name, string options) +bool COPKGManager::installPackage(const string& pkg_name, string options, bool force_configure) { //check package size...cancel installation if size check failed if (!checkSize(pkg_name)){ @@ -734,10 +736,13 @@ bool COPKGManager::installPackage(const string& pkg_name, string options) string opts = " " + options + " "; int r = execCmd(pkg_types[OM_INSTALL] + opts + pkg_name, true, true); - if (r) + if (r){ showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + opts + pkg_name); - else + }else{ + if (force_configure) + execCmd(pkg_types[OM_CONFIGURE] + pkg_name, false, false); installed = true; + } } return true; diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 338a3d160..97b736d90 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -118,7 +118,7 @@ class COPKGManager : public CMenuTarget int exec(CMenuTarget* parent, const std::string & actionKey); static bool hasOpkgSupport(); bool checkUpdates(const std::string & package_name = std::string(), bool show_progress = true); - bool installPackage(const std::string& pkg_name, std::string options = std::string()); + bool installPackage(const std::string& pkg_name, std::string options = std::string(), bool force_configure = false); bool checkSize(const std::string& pkg_name); }; #endif From cceef62661cf7bd484a11463246dd413ff288673 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 23 May 2015 00:20:28 +0200 Subject: [PATCH 090/110] COPKGManager: optimize check size To calculate the required size for installation here we make a quasi-dry run, it is a bit awkward, but relatively specific, other solutions are welcome. We create a temporary test directory and fill it with downloaded or user uploaded package file. Then we unpack the package and change into temporary testing directory. The required size results from the size of generated folders and subfolders. TODO: size of dependencies are not really considered --- src/gui/opkg_manager.cpp | 84 ++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 629b3f021..4571480e3 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -57,6 +57,7 @@ /* later this can be changed to just "opkg" */ #define OPKG_CL "opkg-cl" #define OPKG_TMP_DIR "/tmp/.opkg" +#define OPKG_TEST_DIR OPKG_TMP_DIR "/test" #define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=" OPKG_TMP_DIR @@ -76,6 +77,7 @@ enum OM_INSTALL, OM_STATUS, OM_CONFIGURE, + OM_DOWNLOAD, OM_MAX }; @@ -90,7 +92,8 @@ static const string pkg_types[OM_MAX] = OPKG_CL " info ", OPKG_CL OPKG_CL_CONFIG_OPTIONS " install ", OPKG_CL " status ", - OPKG_CL " configure " + OPKG_CL " configure ", + OPKG_CL " download " }; COPKGManager::COPKGManager(): opkg_conf('\t') @@ -98,7 +101,7 @@ COPKGManager::COPKGManager(): opkg_conf('\t') width = 80; //define default dest keys - string dest_defaults[] = {"/", OPKG_TMP_DIR, "/mnt"}; + string dest_defaults[] = {"/", OPKG_TEST_DIR, OPKG_TMP_DIR, "/mnt"}; for(size_t i=0; i> pkg_size; + string pkg_file = pkg_name; + string plain_pkg = getBaseName(pkg_file); - string status = getPkgInfo(pkg_name, "Status"); - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] Status of %s: %s\n", __func__, __LINE__, pkg_name.c_str(), status.c_str()); - - //get available size + //get available root fs size //TODO: Check writability! struct statfs root_fs; - statfs("/",&root_fs); + statfs("/", &root_fs); u_int64_t free_size = root_fs.f_bfree*root_fs.f_bsize; - //only for sure, it's more secure for users to abort installation if is available size too small + /* - * FIXME: Package size is not really the same like required/recommended size, because of unknown compression factor of package, possible options like cache, different tmp-dir size, - * size of required dependencies eg. are still not considered. - * Experience values are nearly to factor 2.1 to 2.5 related to package size. That's generously but not 100% sure! + * To calculate the required size for installation here we make a quasi-dry run, + * it is a bit awkward, but relatively specific, other solutions are welcome. + * We create a temporary test directory and fill it with downloaded or user uploaded package file. + * Then we unpack the package and change into temporary testing directory. + * The required size results from the size of generated folders and subfolders. + * TODO: size of dependencies are not really considered */ - float pkg_raw_size = float(pkg_size); - u_int64_t req_size = u_int64_t(pkg_raw_size*2.5); + CFileHelpers fh; + + //create test pkg dir + string tmp_dest = OPKG_TEST_DIR; + tmp_dest += "/package"; + fh.createDir(tmp_dest); + + //change into test dir + chdir(OPKG_TEST_DIR); + + //copy package into test dir + string tmp_dest_file = OPKG_TEST_DIR; + tmp_dest_file += "/" + plain_pkg; + if(!access( pkg_file.c_str(), F_OK)) //use local package + fh.copyFile(pkg_file.c_str(), tmp_dest_file.c_str(), 0644); + else + execCmd(pkg_types[OM_DOWNLOAD] + plain_pkg); //download package + + //unpack package into test dir + string ar = "ar -x " + plain_pkg; + execCmd(ar); + + //untar package into test directory + string untar_tar_cmd = "tar -xf "; + untar_tar_cmd += OPKG_TEST_DIR; + untar_tar_cmd += "/data.tar.gz -C " + tmp_dest; + execCmd(untar_tar_cmd); + + //get new current required minimal size from dry run test dir + u_int64_t req_size = fh.getDirSize(tmp_dest); + + //clean up + fh.removeDir(OPKG_TEST_DIR); + dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [required size=%lld (free size: %lld)]\n", __func__, __LINE__, pkg_name.c_str(), req_size, free_size); if (free_size < req_size){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld package size=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, pkg_size, req_size); - //exit with false if package not installed, allready installed packages will be be removed before install, therefore it should be enough disk space available -// if (status.empty()) - return false; + //exit if required size too much + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%lld (recommended: %lld)\n", __func__, __LINE__, free_size, req_size); + return false; } return true; } @@ -475,8 +506,11 @@ int COPKGManager::showMenu() if (!access( "/tmp/.force_restart", F_OK)) exit_action = "restart"; //reboot stb: forced - if (!access( "/tmp/.reboot", F_OK)) - exit_action = "reboot"; + if (!access( "/tmp/.reboot", F_OK)){ + //ShowHint("", "Reboot ...", 300, 3); //TODO + g_RCInput->postMsg( NeutrinoMessages::REBOOT, 0); + res = menu_return::RETURN_EXIT_ALL; + } } delete menu; @@ -740,7 +774,7 @@ bool COPKGManager::installPackage(const string& pkg_name, string options, bool f showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + opts + pkg_name); }else{ if (force_configure) - execCmd(pkg_types[OM_CONFIGURE] + pkg_name, false, false); + execCmd(pkg_types[OM_CONFIGURE] + getBlankPkgName(pkg_name), false, false); installed = true; } } From ce3c4d3b04227fd66df8de3ea6a072ec082250cd Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 7 Feb 2015 23:41:08 +0100 Subject: [PATCH 091/110] COPKGManager: add functions isInstalled() and isUpgradable() --- src/gui/opkg_manager.cpp | 24 ++++++++++++++++++++++++ src/gui/opkg_manager.h | 4 +++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 4571480e3..9e6f8f2de 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -782,6 +782,30 @@ bool COPKGManager::installPackage(const string& pkg_name, string options, bool f return true; } +bool COPKGManager::isInstalled(const string& pkg_name) +{ + string package = pkg_name; + package = getBaseName(package); + + map::iterator it = pkg_map.find(package); + if (it != pkg_map.end()) + if (it->second.installed) + return true; + return false; +} + +bool COPKGManager::isUpgradable(const string& pkg_name) +{ + string package = pkg_name; + package = getBaseName(package); + + map::iterator it = pkg_map.find(package); + if (it != pkg_map.end()) + if (it->second.upgradable) + return true; + return false; +} + void COPKGManager::showMenuConfigFeed(CMenuWidget *feed_menu) { diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 97b736d90..109672f9d 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -66,7 +66,7 @@ class COPKGManager : public CMenuTarget bool expert_mode; int menu_offset; std::string *local_dir; - + bool has_err; std::string err_msg; @@ -76,6 +76,8 @@ class COPKGManager : public CMenuTarget }; void getPkgData(const int pkg_content_id); std::string getBlankPkgName(const std::string& line); + bool isInstalled(const std::string& pkg_name); + bool isUpgradable(const std::string& pkg_name); /* * Gets an info from opkg command info or status from a package via keywords as std::string From 54d3ad261cce7e8125a02168dec8a0d2c65d7bd6 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 8 Feb 2015 00:30:58 +0100 Subject: [PATCH 092/110] COPKGManager: use wildcard char for ar command This fixes unpacking of local and downloaded packages. --- src/gui/opkg_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 9e6f8f2de..6c14fb507 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -257,7 +257,7 @@ bool COPKGManager::checkSize(const string& pkg_name) execCmd(pkg_types[OM_DOWNLOAD] + plain_pkg); //download package //unpack package into test dir - string ar = "ar -x " + plain_pkg; + string ar = "ar -x " + plain_pkg + char(0x2a); execCmd(ar); //untar package into test directory From 337cc097c83cda927beeebc1c1f3bfc3a71b78fe Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 8 Feb 2015 00:57:49 +0100 Subject: [PATCH 093/110] COPKGManager: exit check size if package already installed Old files will be remove during installation, so it should be enough size. --- src/gui/opkg_manager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 6c14fb507..ea56edfc3 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -224,6 +224,10 @@ bool COPKGManager::checkSize(const string& pkg_name) string pkg_file = pkg_name; string plain_pkg = getBaseName(pkg_file); + //exit check size if package already installed, because of auto remove of old stuff during installation + if (isInstalled(plain_pkg)) + return true; + //get available root fs size //TODO: Check writability! struct statfs root_fs; From ae66014102cc66d8b63e3ed5f7e526a9f007e10b Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 8 Feb 2015 01:29:15 +0100 Subject: [PATCH 094/110] COPKGManager: defuse effect of resolve_conffiles errors --- src/gui/opkg_manager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index ea56edfc3..fe759b58e 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -718,6 +718,13 @@ void COPKGManager::handleShellOutput(string& cur_line) dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: Duplicate option cache, please check opkg config file!\n", __func__, __LINE__); has_err = false; } + /*resolve_conffiles: already existent configfiles are not installed, but renamed in the same directory, + * NOTE: It's not fine but not really bad. Files should be installed separate or user can change manually + */ + if (cur_line.find("Existing conffile") != string::npos){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: Existing conffile(s) not changed!\n", __func__, __LINE__); + has_err = false; + } //find obvious errors //download error: From 982fbb962e99d53ab7285706e18c5cf121d50833 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 24 Mar 2015 14:46:18 +0100 Subject: [PATCH 095/110] CShellWindow: use slots for ACKNOWLEDGE_EVENT mode results --- src/gui/widget/shellwindow.cpp | 27 +++++++++++++++---------- src/gui/widget/shellwindow.h | 37 ++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index d7e4c7f9a..c108e3edf 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -156,7 +156,8 @@ void CShellWindow::exec() //callback for line handler std::string s_output = std::string((output)); - OnShellOutputLoop(s_output); + OnShellOutputLoop(s_output, res, &ok); + dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] res=%d ok=%d\n", __func__, __LINE__, *res, ok); if (lines.size() > lines_max) lines.pop_front(); txt = ""; @@ -200,12 +201,14 @@ void CShellWindow::exec() errno = 0; int r = waitpid(pid, &s, 0); - if (res) { - dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] res=%d, error[%d]: %s\n", __func__, __LINE__, *res, errno, strerror(errno)); - if (r == -1) - *res = errno; - else - *res = WEXITSTATUS(s); + if (res){ + //if res value was generated inside signal, then use foreign res from signal instead own res value + if (OnShellOutputLoop.empty()){ + if (r == -1) + *res = errno; + else + *res = WEXITSTATUS(s); + } } showResult(); @@ -220,12 +223,14 @@ void CShellWindow::showResult() if (mode & ACKNOWLEDGE){ show_button = true; } - else if (mode & ACKNOWLEDGE_MSG){ + else if (mode & ACKNOWLEDGE_EVENT){ if (*res != 0){ - DisplayErrorMessage("Please press button"); + OnResultError(res); + if (OnResultError.empty()) + DisplayErrorMessage("Error while execution of task. Please see window for details!"); show_button = true; }else{ - DisplayInfoMessage("...ready. Please press OK"); + OnResultOk(res); exit = true; } } @@ -235,7 +240,7 @@ void CShellWindow::showResult() int b_height = 35; int xpos = frameBuffer->getScreenWidth() - b_width; int ypos = frameBuffer->getScreenHeight() - b_height; - CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_OK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); + CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_BACK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); btn.paint(); } diff --git a/src/gui/widget/shellwindow.h b/src/gui/widget/shellwindow.h index 45d4cda84..9812c4b11 100644 --- a/src/gui/widget/shellwindow.h +++ b/src/gui/widget/shellwindow.h @@ -47,9 +47,9 @@ class CShellWindow : public sigc::trackable public: enum shellwindow_modes { - VERBOSE = 1, - ACKNOWLEDGE = 2, - ACKNOWLEDGE_MSG = 4 + VERBOSE = 1, + ACKNOWLEDGE = 2, + ACKNOWLEDGE_EVENT = 4 }; CShellWindow(const std::string &Command, const int Mode = 0, int* Res = NULL, bool auto_exec = true); ~CShellWindow(); @@ -79,7 +79,36 @@ class CShellWindow : public sigc::trackable shell.exec(); ...other code... */ - sigc::signal OnShellOutputLoop; + sigc::signal OnShellOutputLoop; + + /*! + signal/event handler runs after task is finished. + NOTE: works only with ACKNOWLEDGE_EVENT mode + After executed task comes a default messages (see method showResult()), but with these slots it is possible to use other messages + or any desired action without any touching this class. + Example for implementation in foreign class let show an alternate message than default message: + ...your code... + //assuming in your foreign class is declared a member function named YourMemberFunction() without return value and int* as parmeter This method should run + instead the default message. + + //declare a slot with return value as 'void' and wihout any parameter + sigc::slot sl; + + //fill the slot with your member function in your class with your action + sl = sigc::mem_fun(*this, &CYourClass::YourMemberFunction); + + //create the CShellWindow object in verbose mode, important: parameter 'auto_exec' must be set to 'false', so it is possible to connect the slot before engages the exec() methode + CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res, false); + + //connect slot + shell1.OnResultError.connect(sl); + + //now exec... + shell.exec(); + ...other code... + */ + sigc::signal OnResultError; + sigc::signal OnResultOk; }; #endif From ed5bbdc5404c3ad9c95393607f63d9ca22d614ec Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sat, 23 May 2015 22:52:57 +0200 Subject: [PATCH 096/110] CShellWindow/COPKGManager: handle some error from shell output TODO: add missing handlers --- src/gui/opkg_manager.cpp | 145 +++++++++++++++++++++------------ src/gui/opkg_manager.h | 30 ++++++- src/gui/widget/shellwindow.cpp | 3 +- src/gui/widget/shellwindow.h | 16 ++-- 4 files changed, 133 insertions(+), 61 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index fe759b58e..6870ea042 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -54,6 +54,7 @@ #include #include #include +#include /* later this can be changed to just "opkg" */ #define OPKG_CL "opkg-cl" #define OPKG_TMP_DIR "/tmp/.opkg" @@ -98,6 +99,7 @@ static const string pkg_types[OM_MAX] = COPKGManager::COPKGManager(): opkg_conf('\t') { + OM_ERRORS(); width = 80; //define default dest keys @@ -669,11 +671,21 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) has_err = false; tmp_str.clear(); err_msg = ""; + bool ok = true; if (verbose) { - sigc::slot1 sl; - sl = sigc::mem_fun(*this, &COPKGManager::handleShellOutput); - CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res, false); - shell.OnShellOutputLoop.connect(sl); + //create CShellWindow object + CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_EVENT : 0), &res, false); + + //init slot for shell output handler with 3 args, no return value, and connect with loop handler inside of CShellWindow object + sigc::slot3 sl_shell; + sl_shell = sigc::mem_fun(*this, &COPKGManager::handleShellOutput); + shell.OnShellOutputLoop.connect(sl_shell); +#if 0 + //demo for custom error message inside shell window loop + sigc::slot1 sl1; + sl1 = sigc::mem_fun(*this, &COPKGManager::showErr); + shell.OnResultError.connect(sl1); +#endif shell.exec(); } else { cmd += " 2>&1"; @@ -684,84 +696,98 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) return -1; } char buf[256]; - while (fgets(buf, sizeof(buf), f)) - { + do { string line(buf); trim(line); + handleShellOutput(&line, &res, &ok); dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] %s [error %d]\n", __func__, __LINE__, line.c_str(), has_err); - handleShellOutput(line); - } + } while (fgets(buf, sizeof(buf), f) && ok); + fclose(f); } - if (has_err){ - return -1; - } - return res; } -void COPKGManager::handleShellOutput(string& cur_line) +void COPKGManager::handleShellOutput(string* cur_line, int* res, bool* ok) { - size_t pos2 = cur_line.find("Collected errors:"); + //hold current res value + int _res = *res; + + //use current line + string line = *cur_line; + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] come into shell handler with res: %d\n", __func__, __LINE__, _res); + + //detect any collected error + size_t pos2 = line.find("Collected errors:"); if (pos2 != string::npos) has_err = true; - //check for collected errors and build a message for screen if errors available + //check for collected errors and set res value if (has_err){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] result: %s\n", __func__, __LINE__, cur_line.c_str()); + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] result: %s\n", __func__, __LINE__, line.c_str()); - //trivial errors: /*duplicate option cache: option is defined in OPKG_CL_CONFIG_OPTIONS, * NOTE: if found first cache option in the opkg.conf file, this will be preferred and it's not really an error! */ - if (cur_line.find("Duplicate option cache") != string::npos){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: Duplicate option cache, please check opkg config file!\n", __func__, __LINE__); + if (line.find("Duplicate option cache") != string::npos){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: %s\n", __func__, __LINE__, line.c_str()); + *ok = true; has_err = false; + *res = OM_SUCCESS; + return; } /*resolve_conffiles: already existent configfiles are not installed, but renamed in the same directory, * NOTE: It's not fine but not really bad. Files should be installed separate or user can change manually */ - if (cur_line.find("Existing conffile") != string::npos){ - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: Existing conffile(s) not changed!\n", __func__, __LINE__); + if (line.find("Existing conffile") != string::npos){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: %s\n", __func__, __LINE__, line.c_str()); + *ok = true; has_err = false; + *res = OM_SUCCESS; + return; } - - //find obvious errors //download error: - if (cur_line.find("opkg_download:") != string::npos){ - err_msg += "Network error! Please check your network connection!\n"; - has_err = true; - } - //install errors: - if (cur_line.find("opkg_install_pkg") != string::npos){ - err_msg += "Update not possible!\n"; - has_err = true; - } - if (cur_line.find("opkg_install_cmd") != string::npos){ - err_msg += "Cannot install package!\n"; - has_err = true; - } - if (cur_line.find("No space left on device") != string::npos){ - err_msg += "Not enough space available!\n"; - has_err = true; - } - if (has_err) + if (line.find("opkg_download:") != string::npos){ + *res = OM_DOWNLOAD_ERR; + *ok = false; return; + } + //not enough space + if (line.find("No space left on device") != string::npos){ + *res = OM_OUT_OF_SPACE_ERR; + *ok = false; + return; + } + //deps + if (line.find("satisfy_dependencies") != string::npos){ + *res = OM_UNSATISFIED_DEPS_ERR; + *ok = false; + return; + } + //unknown error + if (*ok){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] ERROR: unhandled error %s\n", __func__, __LINE__, line.c_str()); + *res = OM_UNKNOWN_ERR; + *ok = false; + return; + } - //add unknown errors: - size_t pos1 = cur_line.find(" * "); - if (pos1 != string::npos){ - string str = cur_line.substr(pos1, cur_line.length()-pos1); - err_msg += str.replace(pos1, 3,"") + "\n"; - has_err = true; + if (!has_err){ + *ok = true; + *res = OM_SUCCESS; } - if (has_err) - return; } - if (!has_err) - tmp_str += cur_line + "\n"; + + *res = _res; } +void COPKGManager::showErr(int* res) +{ + string err = to_string(*res); + string errtest = err_list[1].id; + DisplayErrorMessage(errtest.c_str()); +} + void COPKGManager::showError(const char* local_msg, char* err_message, const string& command) { string msg = local_msg ? string(local_msg) + "\n" : ""; @@ -782,7 +808,22 @@ bool COPKGManager::installPackage(const string& pkg_name, string options, bool f int r = execCmd(pkg_types[OM_INSTALL] + opts + pkg_name, true, true); if (r){ - showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + opts + pkg_name); + switch(r){ + case OM_OUT_OF_SPACE_ERR: + DisplayErrorMessage("Not enough space available"); + break; + case OM_DOWNLOAD_ERR: + DisplayErrorMessage("Can't download package. Check network!"); + break; + case OM_UNSATISFIED_DEPS_ERR:{ + int msgRet = ShowMsg("Installation", "Unsatisfied deps while installation! Try to repeat to force dependencies!", CMessageBox::mbrCancel, CMessageBox::mbYes | CMessageBox::mbNo, NULL, 600, -1); + if (msgRet == CMessageBox::mbrYes) + return installPackage(pkg_name, "--force-depends"); + break; + } + default: + showError(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL), strerror(errno), pkg_types[OM_INSTALL] + opts + pkg_name); + } }else{ if (force_configure) execCmd(pkg_types[OM_CONFIGURE] + getBlankPkgName(pkg_name), false, false); diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 109672f9d..d58f0af84 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -68,6 +68,34 @@ class COPKGManager : public CMenuTarget std::string *local_dir; bool has_err; + typedef struct om_error_data_t + { + std::string id; + int num; + }om_error_struct_t; + //error types + enum + { + OM_UNKNOWN_ERR =-1, + OM_SUCCESS = 0, + OM_UNSATISFIED_DEPS_ERR = 5, + OM_DOWNLOAD_ERR = 11, + OM_CONFLICT_ERR = 12, + OM_OUT_OF_SPACE_ERR = 15, + OM_PREREM_SCRIPT_ERR = 16, + }; + om_error_data_t *err_list; + void OM_ERRORS() + { + static om_error_data_t errlist[] = { { "Cannot satisfy the following dependencies" , OM_UNSATISFIED_DEPS_ERR }, + { "No space left on device" , OM_OUT_OF_SPACE_ERR }, + { "The following packages conflict" , OM_CONFLICT_ERR }, + { "Only have" , OM_OUT_OF_SPACE_ERR }, + { "prerm script for package" , OM_PREREM_SCRIPT_ERR }, + } ; + err_list = errlist; + }; + void showErr(int* res); std::string err_msg; int execCmd(const char* cmdstr, bool verbose = false, bool acknowledge = false); @@ -100,7 +128,7 @@ class COPKGManager : public CMenuTarget bool badpackage(std::string &s); void showError(const char* local_msg, char* err_msg, const std::string& command); int doUpdate(); - void handleShellOutput(std::string& cur_line); + void handleShellOutput(std::string* cur_line, int* res, bool* ok); struct pkg { std::string name; diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index c108e3edf..2f304d774 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -156,8 +156,9 @@ void CShellWindow::exec() //callback for line handler std::string s_output = std::string((output)); - OnShellOutputLoop(s_output, res, &ok); + OnShellOutputLoop(&s_output, res, &ok); dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] res=%d ok=%d\n", __func__, __LINE__, *res, ok); + if (lines.size() > lines_max) lines.pop_front(); txt = ""; diff --git a/src/gui/widget/shellwindow.h b/src/gui/widget/shellwindow.h index 9812c4b11..2f1171dd5 100644 --- a/src/gui/widget/shellwindow.h +++ b/src/gui/widget/shellwindow.h @@ -64,22 +64,22 @@ class CShellWindow : public sigc::trackable //Tis function should handle the shell output! //declare a slot with return value as 'void' and parameter as 'string', here by rev! - sigc::slot1 sl; + sigc::slot1 sl_shell_output; //fill the slot with your member function in your class that do evaluate the output lines - sl = sigc::mem_fun(*this, &CYourClass::YourMemberFunction); + sl_shell_output = sigc::mem_fun(*this, &CYourClass::YourMemberFunction); //create the CShellWindow object in verbose mode, important: parameter 'auto_exec' must be set to 'false', so it is possible to connect the slot before engages the exec() methode CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res, false); //connect slot - shell.OnShellOutputLoop.connect(sl); + shell.OnShellOutputLoop.connect(sl_shell_output); //now exec... shell.exec(); ...other code... */ - sigc::signal OnShellOutputLoop; + sigc::signal OnShellOutputLoop; /*! signal/event handler runs after task is finished. @@ -92,20 +92,22 @@ class CShellWindow : public sigc::trackable instead the default message. //declare a slot with return value as 'void' and wihout any parameter - sigc::slot sl; + sigc::slot sl_result_err; //fill the slot with your member function in your class with your action - sl = sigc::mem_fun(*this, &CYourClass::YourMemberFunction); + sl_result_err = sigc::mem_fun(*this, &CYourClass::YourMemberFunction); //create the CShellWindow object in verbose mode, important: parameter 'auto_exec' must be set to 'false', so it is possible to connect the slot before engages the exec() methode CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_MSG : 0), &res, false); //connect slot - shell1.OnResultError.connect(sl); + shell1.OnResultError.connect(sl_result_err); //now exec... shell.exec(); ...other code... + + Use of OnResultOk is similar with OnResultError. */ sigc::signal OnResultError; sigc::signal OnResultOk; From acdc74950a0fd0b32602a6f3e647b5239424cd06 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 24 May 2015 20:13:25 +0200 Subject: [PATCH 097/110] COPKGManager: use empty string as default parameter for full info --- src/gui/opkg_manager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index d58f0af84..2d5faaa07 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -115,7 +115,7 @@ class COPKGManager : public CMenuTarget * These kewords are to find in the control package inside of the opkg package file and the package list. * 3rd parameter sets the sub command status or info. For more details, take a look to the opkg commands via command line. */ - std::string getPkgInfo(const std::string& pkg_name, const std::string& pkg_key, bool current_status = false); + std::string getPkgInfo(const std::string& pkg_name, const std::string& pkg_key = std::string(), bool current_status = false); //Does the same like getPkgInfo(), but only for status std::string getPkgStatus(const std::string& pkg_name, const std::string& pkg_key){return getPkgInfo(pkg_name, pkg_key, true);} From f3d7bdda1e0c24570146ed76a6ad6bdbbabaf543 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 24 May 2015 20:15:21 +0200 Subject: [PATCH 098/110] COPKGManager: show package info via message box instead shell window --- src/gui/opkg_manager.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 6870ea042..7a347bb10 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -151,11 +151,14 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) return res; } if (actionKey == "rc_info") { - if (selected < 0 || selected >= (int) pkg_vec.size()) + if (selected < 0 || selected >= (int) pkg_vec.size()){ + DisplayInfoMessage("No information available! Please first select a package!"); return menu_return::RETURN_NONE; - if (parent) - parent->hide(); - execCmd(pkg_types[OM_INFO] + pkg_vec[selected]->name, true, true); + } + //show package info... + bool is_installed = pkg_vec[selected]->installed; + string infostr = getPkgInfo(pkg_vec[selected]->name, "", is_installed /*status or info*/); + DisplayInfoMessage(infostr.c_str()); return res; } if (actionKey == "rc_yellow") { @@ -637,10 +640,12 @@ string COPKGManager::getBlankPkgName(const string& line) string COPKGManager::getPkgInfo(const string& pkg_name, const string& pkg_key, bool current_status) { - tmp_str.clear(); execCmd(pkg_types[current_status ? OM_STATUS : OM_INFO] + pkg_name, false, true); dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] [data: %s]\n", __func__, __LINE__, tmp_str.c_str()); + if (pkg_key.empty()) + return tmp_str; + return getKeyInfo(tmp_str, pkg_key, ":"); } @@ -715,7 +720,11 @@ void COPKGManager::handleShellOutput(string* cur_line, int* res, bool* ok) //use current line string line = *cur_line; - dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] come into shell handler with res: %d\n", __func__, __LINE__, _res); + + //tmp_str contains all output lines and is available in the object scope of this + tmp_str += line + '\n'; + + //dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] come into shell handler with res: %d, line = %s\n", __func__, __LINE__, _res, line.c_str()); //detect any collected error size_t pos2 = line.find("Collected errors:"); From cc49d5a714b09d79c4b371215e68cce3a20cd83d Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 24 May 2015 20:57:21 +0200 Subject: [PATCH 099/110] CShellWindow: disable not required screean saving on text paint --- src/gui/widget/shellwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 2f304d774..5ed86d06c 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -92,6 +92,7 @@ void CShellWindow::exec() list lines; CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenX(), w_shell, h_shell); textBox = new CTextBox(cmd.c_str(), font, CTextBox::BOTTOM, &textBoxPosition); + textBox->enableSaveScreen(false); struct pollfd fds; fds.fd = fileno(f); fds.events = POLLIN | POLLHUP | POLLERR; From 9a6aae8f4928e65fee58b6b55c5a9ab8b6c9aba5 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 25 May 2015 15:25:32 +0200 Subject: [PATCH 100/110] COPKGManager: use parameters for errror message and additional text as option --- src/gui/opkg_manager.cpp | 9 +++++---- src/gui/opkg_manager.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 7a347bb10..b2d64438e 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -797,12 +797,13 @@ void COPKGManager::showErr(int* res) DisplayErrorMessage(errtest.c_str()); } -void COPKGManager::showError(const char* local_msg, char* err_message, const string& command) +void COPKGManager::showError(const char* local_msg, char* err_message, const string& additional_text) { string msg = local_msg ? string(local_msg) + "\n" : ""; - msg += err_msg + "\n"; - msg += string(err_message) + ":\n"; - msg += command; + if (err_message) + msg += string(err_message) + ":\n"; + if (!additional_text.empty()) + msg += additional_text; DisplayErrorMessage(msg.c_str()); } diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 2d5faaa07..6ef3fe83b 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -126,7 +126,7 @@ class COPKGManager : public CMenuTarget void updateMenu(); void refreshMenu(); bool badpackage(std::string &s); - void showError(const char* local_msg, char* err_msg, const std::string& command); + void showError(const char* local_msg, char* err_msg = NULL, const std::string& additional_text = std::string()); int doUpdate(); void handleShellOutput(std::string* cur_line, int* res, bool* ok); From 79f66537f0fe5fb9dafd729a597379daa21d23c3 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 25 May 2015 15:31:20 +0200 Subject: [PATCH 101/110] COPKGManager: remove useless err_msg var, replaced by tmp_str --- src/gui/opkg_manager.cpp | 3 +-- src/gui/opkg_manager.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index b2d64438e..bdf2792d9 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -427,7 +427,7 @@ int COPKGManager::doUpdate() { int r = execCmd(pkg_types[OM_UPDATE]); if (r == -1) { - string msg = string(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE)) + "\n" + err_msg; + string msg = string(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE)); DisplayErrorMessage(msg.c_str()); return r; } @@ -675,7 +675,6 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) int res = 0; has_err = false; tmp_str.clear(); - err_msg = ""; bool ok = true; if (verbose) { //create CShellWindow object diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 6ef3fe83b..0403903db 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -96,7 +96,6 @@ class COPKGManager : public CMenuTarget err_list = errlist; }; void showErr(int* res); - std::string err_msg; int execCmd(const char* cmdstr, bool verbose = false, bool acknowledge = false); int execCmd(std::string cmdstr, bool verbose = false, bool acknowledge = false) { From 5f1708b6e1ba5bb8fa43a84f4213f65621283abe Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 25 May 2015 16:09:00 +0200 Subject: [PATCH 102/110] CShellWindow: use my_system instead system, avoids possible errors --- src/gui/widget/shellwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 5ed86d06c..370326e70 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -64,7 +64,7 @@ void CShellWindow::exec() std::string cmd; if (!(mode & VERBOSE)){ cmd = "PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin ; export PATH ; " + command + " 2>/dev/null >&2"; - int r = system(cmd.c_str()); + int r = my_system(cmd.c_str()); if (res) { if (r == -1) *res = r; From 8edbbaddc0c1886a7b4e92f4d169f41c2581b420 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 25 May 2015 16:46:29 +0200 Subject: [PATCH 103/110] COPKGManager: use strictly shell window object to execute commands --- src/gui/opkg_manager.cpp | 41 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index bdf2792d9..4826b0a44 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -676,39 +676,22 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) has_err = false; tmp_str.clear(); bool ok = true; - if (verbose) { - //create CShellWindow object - CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_EVENT : 0), &res, false); - //init slot for shell output handler with 3 args, no return value, and connect with loop handler inside of CShellWindow object - sigc::slot3 sl_shell; - sl_shell = sigc::mem_fun(*this, &COPKGManager::handleShellOutput); - shell.OnShellOutputLoop.connect(sl_shell); + //create CShellWindow object + CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_EVENT : 0), &res, false); + + //init slot for shell output handler with 3 args, no return value, and connect with loop handler inside of CShellWindow object + sigc::slot3 sl_shell; + sl_shell = sigc::mem_fun(*this, &COPKGManager::handleShellOutput); + shell.OnShellOutputLoop.connect(sl_shell); #if 0 - //demo for custom error message inside shell window loop - sigc::slot1 sl1; - sl1 = sigc::mem_fun(*this, &COPKGManager::showErr); - shell.OnResultError.connect(sl1); + //demo for custom error message inside shell window loop + sigc::slot1 sl1; + sl1 = sigc::mem_fun(*this, &COPKGManager::showErr); + shell.OnResultError.connect(sl1); #endif shell.exec(); - } else { - cmd += " 2>&1"; - pid_t pid = 0; - FILE *f = my_popen(pid, cmd.c_str(), "r"); - if (!f) { - showError("OPKG-Error!", strerror(errno), cmd); - return -1; - } - char buf[256]; - do { - string line(buf); - trim(line); - handleShellOutput(&line, &res, &ok); - dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] %s [error %d]\n", __func__, __LINE__, line.c_str(), has_err); - } while (fgets(buf, sizeof(buf), f) && ok); - - fclose(f); - } + return res; } From e1e8cb0142f97a9605c2d845d29c64940296a201 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 28 May 2015 10:27:59 +0200 Subject: [PATCH 104/110] CShellWindow/COPKGManager: rework shell shell mode handling Modes were handled with bool values inside manager and this is not really enough. Now we use the real parameters for more flexibility. --- src/gui/opkg_manager.cpp | 23 +-- src/gui/opkg_manager.h | 7 +- src/gui/widget/shellwindow.cpp | 295 +++++++++++++++++---------------- src/gui/widget/shellwindow.h | 9 +- 4 files changed, 172 insertions(+), 162 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 4826b0a44..35d9800f0 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -41,7 +41,7 @@ #include #include -#include + #include #include #include @@ -145,7 +145,7 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) if (ShowMsg(LOCALE_OPKG_TITLE, loc, CMessageBox::mbrCancel, CMessageBox::mbYes | CMessageBox::mbCancel) != CMessageBox::mbrCancel) { if (parent) parent->hide(); - execCmd(pkg_types[OM_REMOVE] + pkg_vec[selected]->name, true, true); + execCmd(pkg_types[OM_REMOVE] + pkg_vec[selected]->name, CShellWindow::VERBOSE | CShellWindow::ACKNOWLEDGE_EVENT); refreshMenu(); } return res; @@ -192,7 +192,7 @@ int COPKGManager::exec(CMenuTarget* parent, const string &actionKey) if(actionKey == pkg_types[OM_UPGRADE]) { if (parent) parent->hide(); - int r = execCmd(actionKey, true, true); + int r = execCmd(actionKey, CShellWindow::VERBOSE | CShellWindow::ACKNOWLEDGE_EVENT); if (r) { showError(g_Locale->getText(LOCALE_OPKG_FAILURE_UPGRADE), strerror(errno), actionKey); } else @@ -425,9 +425,10 @@ bool COPKGManager::checkUpdates(const std::string & package_name, bool show_prog int COPKGManager::doUpdate() { - int r = execCmd(pkg_types[OM_UPDATE]); - if (r == -1) { + int r = execCmd(pkg_types[OM_UPDATE], CShellWindow::QUIET); + if (r) { string msg = string(g_Locale->getText(LOCALE_OPKG_FAILURE_UPDATE)); + msg += '\n' + tmp_str; DisplayErrorMessage(msg.c_str()); return r; } @@ -640,7 +641,7 @@ string COPKGManager::getBlankPkgName(const string& line) string COPKGManager::getPkgInfo(const string& pkg_name, const string& pkg_key, bool current_status) { - execCmd(pkg_types[current_status ? OM_STATUS : OM_INFO] + pkg_name, false, true); + execCmd(pkg_types[current_status ? OM_STATUS : OM_INFO] + pkg_name, CShellWindow::QUIET); dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] [data: %s]\n", __func__, __LINE__, tmp_str.c_str()); if (pkg_key.empty()) @@ -668,7 +669,7 @@ string COPKGManager::getKeyInfo(const string& input, const std::string& key, con return ""; } -int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) +int COPKGManager::execCmd(const char *cmdstr, int verbose_mode) { fprintf(stderr, "execCmd(%s)\n", cmdstr); string cmd = string(cmdstr); @@ -678,7 +679,7 @@ int COPKGManager::execCmd(const char *cmdstr, bool verbose, bool acknowledge) bool ok = true; //create CShellWindow object - CShellWindow shell(cmd, (verbose ? CShellWindow::VERBOSE : 0) | (acknowledge ? CShellWindow::ACKNOWLEDGE_EVENT : 0), &res, false); + CShellWindow shell(cmd, verbose_mode, &res, false); //init slot for shell output handler with 3 args, no return value, and connect with loop handler inside of CShellWindow object sigc::slot3 sl_shell; @@ -798,7 +799,7 @@ bool COPKGManager::installPackage(const string& pkg_name, string options, bool f else{ string opts = " " + options + " "; - int r = execCmd(pkg_types[OM_INSTALL] + opts + pkg_name, true, true); + int r = execCmd(pkg_types[OM_INSTALL] + opts + pkg_name, CShellWindow::VERBOSE | CShellWindow::ACKNOWLEDGE_EVENT); if (r){ switch(r){ case OM_OUT_OF_SPACE_ERR: @@ -818,8 +819,8 @@ bool COPKGManager::installPackage(const string& pkg_name, string options, bool f } }else{ if (force_configure) - execCmd(pkg_types[OM_CONFIGURE] + getBlankPkgName(pkg_name), false, false); - installed = true; + execCmd(pkg_types[OM_CONFIGURE] + getBlankPkgName(pkg_name), 0); + installed = true; //TODO: catch real result } } diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 0403903db..6d81e3428 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -32,6 +32,7 @@ #define __OPKG_MANAGER__ #include +#include #include #include #include @@ -97,9 +98,9 @@ class COPKGManager : public CMenuTarget }; void showErr(int* res); - int execCmd(const char* cmdstr, bool verbose = false, bool acknowledge = false); - int execCmd(std::string cmdstr, bool verbose = false, bool acknowledge = false) { - return execCmd(cmdstr.c_str(), verbose, acknowledge); + int execCmd(const char* cmdstr, int verbose_mode = 0); + int execCmd(std::string cmdstr, int verbose_mode = 0) { + return execCmd(cmdstr.c_str(), verbose_mode); }; void getPkgData(const int pkg_content_id); std::string getBlankPkgName(const std::string& line); diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 370326e70..da1f1ed53 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -62,7 +62,7 @@ CShellWindow::CShellWindow(const std::string &Command, const int Mode, int *Res, void CShellWindow::exec() { std::string cmd; - if (!(mode & VERBOSE)){ + if (mode == 0){ cmd = "PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin ; export PATH ; " + command + " 2>/dev/null >&2"; int r = my_system(cmd.c_str()); if (res) { @@ -72,148 +72,152 @@ void CShellWindow::exec() *res = WEXITSTATUS(r); dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] Error! system returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str()); } - return; } + else { + pid_t pid = 0; + cmd = command + " 2>&1"; + FILE *f = my_popen(pid, cmd.c_str(), "r"); + if (!f) { + if (res) + *res = -1; + dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] Error! my_popen returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str()); + return; + } - pid_t pid = 0; - cmd = command + " 2>&1"; - FILE *f = my_popen(pid, cmd.c_str(), "r"); - if (!f) { - if (res) - *res = -1; - dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] Error! my_popen returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str()); - return; - } + Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]; + int h_shell = frameBuffer->getScreenHeight(); + int w_shell = frameBuffer->getScreenWidth(); + unsigned int lines_max = h_shell / font->getHeight(); + list lines; + CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenX(), w_shell, h_shell); + if (textBox == NULL){ + textBox = new CTextBox(cmd.c_str(), font, CTextBox::BOTTOM, &textBoxPosition); + textBox->enableSaveScreen(false); + } + struct pollfd fds; + fds.fd = fileno(f); + fds.events = POLLIN | POLLHUP | POLLERR; + fcntl(fds.fd, F_SETFL, fcntl(fds.fd, F_GETFL, 0) | O_NONBLOCK); - Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]; - int h_shell = frameBuffer->getScreenHeight(); - int w_shell = frameBuffer->getScreenWidth(); - unsigned int lines_max = h_shell / font->getHeight(); - list lines; - CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenX(), w_shell, h_shell); - textBox = new CTextBox(cmd.c_str(), font, CTextBox::BOTTOM, &textBoxPosition); - textBox->enableSaveScreen(false); - struct pollfd fds; - fds.fd = fileno(f); - fds.events = POLLIN | POLLHUP | POLLERR; - fcntl(fds.fd, F_SETFL, fcntl(fds.fd, F_GETFL, 0) | O_NONBLOCK); + struct timeval tv; + gettimeofday(&tv,NULL); + uint64_t lastPaint = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); + bool ok = true, nlseen = false, dirty = false, incomplete = false; + char output[1024]; + std::string txt = ""; + std::string line = ""; - struct timeval tv; - gettimeofday(&tv,NULL); - uint64_t lastPaint = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); - bool ok = true, nlseen = false, dirty = false, incomplete = false; - char output[1024]; - std::string txt = ""; - std::string line = ""; + do { + uint64_t now; + fds.revents = 0; + int r = poll(&fds, 1, 300); + if (r > 0) { + if (!feof(f)) { + gettimeofday(&tv,NULL); + now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); - do { - uint64_t now; - fds.revents = 0; - int r = poll(&fds, 1, 300); - if (r > 0) { - if (!feof(f)) { - gettimeofday(&tv,NULL); - now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); + unsigned int lines_read = 0; + while (fgets(output, sizeof(output), f)) { + char *outputp = output; + dirty = true; - unsigned int lines_read = 0; - while (fgets(output, sizeof(output), f)) { - char *outputp = output; - dirty = true; + for (int i = 0; output[i] && !nlseen; i++) + switch (output[i]) { + case '\b': + if (outputp > output) + outputp--; + *outputp = 0; + break; + case '\r': + outputp = output; + break; + case '\n': + lines_read++; + nlseen = true; + *outputp = 0; + break; + default: + *outputp++ = output[i]; + break; + } - for (int i = 0; output[i] && !nlseen; i++) - switch (output[i]) { - case '\b': - if (outputp > output) - outputp--; - *outputp = 0; - break; - case '\r': - outputp = output; - break; - case '\n': - lines_read++; - nlseen = true; - *outputp = 0; - break; - default: - *outputp++ = output[i]; - break; + if (outputp < output + sizeof(output)) + *outputp = 0; + line += std::string(output); + if (incomplete) + lines.pop_back(); + if (nlseen) { + lines.push_back(line); + line.clear(); + nlseen = false; + incomplete = false; + } else { + lines.push_back(line); + incomplete = true; } - if (outputp < output + sizeof(output)) - *outputp = 0; - line += std::string(output); - if (incomplete) - lines.pop_back(); - if (nlseen) { - lines.push_back(line); - line.clear(); - nlseen = false; - incomplete = false; - } else { - lines.push_back(line); - incomplete = true; - } + //callback for line handler + std::string s_output = std::string((output)); + OnShellOutputLoop(&s_output, res, &ok); + dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] res=%d ok=%d\n", __func__, __LINE__, *res, ok); - //callback for line handler - std::string s_output = std::string((output)); - OnShellOutputLoop(&s_output, res, &ok); - dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] res=%d ok=%d\n", __func__, __LINE__, *res, ok); - - if (lines.size() > lines_max) - lines.pop_front(); - txt = ""; - bool first = true; - for (std::list::const_iterator it = lines.begin(), end = lines.end(); it != end; ++it) { - if (!first) - txt += '\n'; - first = false; - txt += *it; + if (lines.size() > lines_max) + lines.pop_front(); + txt = ""; + bool first = true; + for (std::list::const_iterator it = lines.begin(), end = lines.end(); it != end; ++it) { + if (!first) + txt += '\n'; + first = false; + txt += *it; + } + if (((lines_read == lines_max) && (lastPaint + 100000 < now)) || (lastPaint + 250000 < now)) { + textBox->setText(&txt, textBox->getWindowsPos().iWidth, false); + if (!textBox->isPainted()) + if (mode & VERBOSE) textBox->paint(); + lines_read = 0; + lastPaint = now; + dirty = false; + } } - if (((lines_read == lines_max) && (lastPaint + 100000 < now)) || (lastPaint + 250000 < now)) { - textBox->setText(&txt, textBox->getWindowsPos().iWidth, false); - if (!textBox->isPainted()) - textBox->paint(); - lines_read = 0; - lastPaint = now; - dirty = false; - } - } - } else + } else + ok = false; + } else if (r < 0) ok = false; - } else if (r < 0) - ok = false; - gettimeofday(&tv,NULL); - now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); - if (!ok || (r < 1 && dirty && lastPaint + 250000 < now)) { + gettimeofday(&tv,NULL); + now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); + if (!ok || (r < 1 && dirty && lastPaint + 250000 < now)) { + textBox->setText(&txt, textBox->getWindowsPos().iWidth, false); + if (!textBox->isPainted()) + if (mode & VERBOSE) textBox->paint(); + lastPaint = now; + dirty = false; + } + } while(ok); + + if (mode & VERBOSE) { + txt += "\n...ready"; textBox->setText(&txt, textBox->getWindowsPos().iWidth, false); - if (!textBox->isPainted()) - textBox->paint(); - lastPaint = now; - dirty = false; } - } while(ok); - txt += "\n...ready"; - textBox->setText(&txt, textBox->getWindowsPos().iWidth, false); + fclose(f); + int s; + errno = 0; + int r = waitpid(pid, &s, 0); - fclose(f); - int s; - errno = 0; - int r = waitpid(pid, &s, 0); - - if (res){ - //if res value was generated inside signal, then use foreign res from signal instead own res value - if (OnShellOutputLoop.empty()){ - if (r == -1) - *res = errno; - else - *res = WEXITSTATUS(s); + if (res){ + //if res value was generated inside signal, then use foreign res from signal instead own res value + if (OnShellOutputLoop.empty()){ + if (r == -1) + *res = errno; + else + *res = WEXITSTATUS(s); + } } + + showResult(); } - - showResult(); } void CShellWindow::showResult() @@ -233,31 +237,32 @@ void CShellWindow::showResult() show_button = true; }else{ OnResultOk(res); - exit = true; + exit = true; //TODO: evaluate plausible statement } } - if (show_button){ - int b_width = 150; - int b_height = 35; - int xpos = frameBuffer->getScreenWidth() - b_width; - int ypos = frameBuffer->getScreenHeight() - b_height; - CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_BACK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); - btn.paint(); + if ((mode & VERBOSE)){ + if (show_button){ + int b_width = 150; + int b_height = 35; + int xpos = frameBuffer->getScreenWidth() - b_width; + int ypos = frameBuffer->getScreenHeight() - b_height; + CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_BACK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true); + btn.paint(); + } + + neutrino_msg_t msg; + neutrino_msg_data_t data; + uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]); + + if (!exit) + { + do + g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); + while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout); + } + textBox->hide(); } - - neutrino_msg_t msg; - neutrino_msg_data_t data; - uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]); - - if (!exit) - { - do - g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); - while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout); - } - - textBox->hide(); } } diff --git a/src/gui/widget/shellwindow.h b/src/gui/widget/shellwindow.h index 2f1171dd5..75cbd88f5 100644 --- a/src/gui/widget/shellwindow.h +++ b/src/gui/widget/shellwindow.h @@ -45,11 +45,14 @@ class CShellWindow : public sigc::trackable void showResult(); public: + //shell window modes for handled shell output. //NOTE: mode 0 use only system calls, with unhandled return values and no handled shell output enum shellwindow_modes { - VERBOSE = 1, - ACKNOWLEDGE = 2, - ACKNOWLEDGE_EVENT = 4 + /*SYSTEM = 0, */ + QUIET = 1, // no window + VERBOSE = 2, // show window + ACKNOWLEDGE = 4, // show result button inside window after execution, no message box NOTE: only in VERBOSE mode + ACKNOWLEDGE_EVENT = 8 // same like ACKNOWLEDGE but shows a default error message box or a slot handled action instead default error message box }; CShellWindow(const std::string &Command, const int Mode = 0, int* Res = NULL, bool auto_exec = true); ~CShellWindow(); From 7aafea5f5dc828b115dc66e62ed15a53e671d5e6 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 8 Jun 2015 10:41:59 +0200 Subject: [PATCH 105/110] COPKGManager: use opkg as binary name only, reduce support check deps Some deps are currently not really required. --- src/gui/opkg_manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 35d9800f0..a5990aba2 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -55,8 +55,8 @@ #include #include #include -/* later this can be changed to just "opkg" */ -#define OPKG_CL "opkg-cl" + +#define OPKG_CL "opkg" #define OPKG_TMP_DIR "/tmp/.opkg" #define OPKG_TEST_DIR OPKG_TMP_DIR "/test" #define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=" OPKG_TMP_DIR @@ -533,7 +533,7 @@ int COPKGManager::showMenu() bool COPKGManager::hasOpkgSupport() { - string deps[] = {"/bin/opkg-check-config", "/bin/update-alternatives", "/var/lib/opkg", "/share/opkg/intercept"}; + string deps[] = {"/var/lib/opkg", /*"/bin/opkg-check-config", "/bin/update-alternatives", "/share/opkg/intercept"*/}; if (find_executable(OPKG_CL).empty()) { dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d]" OPKG_CL " executable not found\n", __func__, __LINE__); From 696c70ae13cff6551823c0bfd9de7a0ad80da8e8 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Wed, 10 Jun 2015 08:02:29 +0200 Subject: [PATCH 106/110] COPKGManager: show debug lines on founded bad packages It seems some innocent packages could be filtered but without plausible reason and this should be indicated. --- src/gui/opkg_manager.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index a5990aba2..ea6e917e9 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -324,22 +324,32 @@ static std::string bad_pattern[] = { bool COPKGManager::badpackage(std::string &s) { int i; + string st = ""; for (i = 0; !bad_pattern[i].empty(); i++) { - std::string p = bad_pattern[i]; + string p = bad_pattern[i]; size_t patlen = p.length() - 1; + bool res = false; /* poor man's regex :-) only supported are "^" and "$" */ if (p.substr(patlen, 1) == "$") { /* match at end */ if (s.rfind(p.substr(0, patlen)) == (s.length() - patlen)) - return true; + res = true; } else if (p.substr(0, 1) == "^") { /* match at beginning */ if (s.find(p.substr(1)) == 0) - return true; + res = true; } else { /* match everywhere */ if (s.find(p) != std::string::npos) - return true; + res = true; } + if (res) + st += p + " "; } + + if (!st.empty()){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] found bad package => %s [filtered with %s]\n", __func__, __LINE__, s.c_str(), st.c_str()); + return true; + } + return false; } From 9345f792a7b35f88b8a9eefd4ccee5bbe0a569d1 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 11 Jun 2015 10:27:08 +0200 Subject: [PATCH 107/110] COPKGManager: use config file for bad package detection To detect bad packages, it must be existing a matching pattern list file. Path is defined in OPKG_BAD_PATTERN_LIST_FILE. This gives the option to filter some bad entries in the package listing menue. NOTE: a sample file you should find here as : "/var/tuxbox/config/bad_package_pattern.list.sample". If required, remove the ".sample" extension and change the entries for your requirements --- data/Makefile.am | 2 +- data/bad_package_pattern.list.sample | 11 ++++++ src/gui/opkg_manager.cpp | 50 +++++++++++++++++----------- src/gui/opkg_manager.h | 23 ++++++++++++- 4 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 data/bad_package_pattern.list.sample diff --git a/data/Makefile.am b/data/Makefile.am index 5f4751b23..ef9881b5e 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -5,7 +5,7 @@ SUBDIRS += lcd endif configdir = $(CONFIGDIR) -config_DATA = cables.xml satellites.xml encoding.conf tobackup.conf providermap.xml settingsupdate.conf terrestrial.xml +config_DATA = cables.xml satellites.xml encoding.conf tobackup.conf providermap.xml settingsupdate.conf terrestrial.xml bad_package_pattern.list.sample install-data-hook: $(INSTALL) -d $(DESTDIR)/$(CONFIGDIR)/zapit diff --git a/data/bad_package_pattern.list.sample b/data/bad_package_pattern.list.sample new file mode 100644 index 000000000..221ffa8f7 --- /dev/null +++ b/data/bad_package_pattern.list.sample @@ -0,0 +1,11 @@ +-dev$ +-doc$ +-dbg$ +-ptest$ +-staticdev$ +-locale- +-charmap- +-gconv- +-localedata- +^locale-base- +^perl-module- diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index ea6e917e9..2c1542481 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -55,13 +55,14 @@ #include #include #include +#include #define OPKG_CL "opkg" #define OPKG_TMP_DIR "/tmp/.opkg" #define OPKG_TEST_DIR OPKG_TMP_DIR "/test" #define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=" OPKG_TMP_DIR - +#define OPKG_BAD_PATTERN_LIST_FILE "/var/tuxbox/config/bad_package_pattern.list" #define OPKG_CONFIG_FILE "/etc/opkg/opkg.conf" using namespace std; @@ -113,8 +114,8 @@ COPKGManager::COPKGManager(): opkg_conf('\t') list_upgradeable_done = false; expert_mode = false; local_dir = &g_settings.update_dir_opkg; + v_bad_pattern = getBadPackagePatternList(); CFileHelpers::createDir(OPKG_TMP_DIR); - } COPKGManager::~COPKGManager() @@ -305,29 +306,38 @@ static const struct button_label COPKGManagerFooterButtonsExpert[COPKGManagerFoo { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_OPKG_BUTTON_UNINSTALL } }; -/* TODO: this should go into a config file... */ -static std::string bad_pattern[] = { - "-dev$", - "-doc$", - "-dbg$", - "-ptest$", - "-staticdev$", - "-locale-", - "-charmap-", - "-gconv-", - "-localedata-", - "^locale-base-", - "^perl-module-", - "" -}; +vector COPKGManager::getBadPackagePatternList() +{ + vector v_ret; + + ifstream in (OPKG_BAD_PATTERN_LIST_FILE, ios::in); + if (!in){ + dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] can't open %s, %s\n", __func__, __LINE__, OPKG_BAD_PATTERN_LIST_FILE, strerror(errno)); + return v_ret; + } + string line; + + while(getline(in, line)){ + v_ret.push_back(line); + } + in.close(); + + return v_ret; +} bool COPKGManager::badpackage(std::string &s) { - int i; + if(v_bad_pattern.empty()) + return false; + + size_t i; string st = ""; - for (i = 0; !bad_pattern[i].empty(); i++) + for (i = 0; i < v_bad_pattern.size(); i++) { - string p = bad_pattern[i]; + string p = v_bad_pattern[i]; + if (p.empty()) + continue; + size_t patlen = p.length() - 1; bool res = false; /* poor man's regex :-) only supported are "^" and "$" */ diff --git a/src/gui/opkg_manager.h b/src/gui/opkg_manager.h index 6d81e3428..4979c9c9b 100644 --- a/src/gui/opkg_manager.h +++ b/src/gui/opkg_manager.h @@ -56,6 +56,9 @@ class COPKGManager : public CMenuTarget std::string config_src[OPKG_MAX_FEEDS]; std::vector config_dest; + //filter + std::vector v_bad_pattern; + std::map pkg_map; std::vector pkg_vec; @@ -107,7 +110,7 @@ class COPKGManager : public CMenuTarget bool isInstalled(const std::string& pkg_name); bool isUpgradable(const std::string& pkg_name); - /* + /*! * Gets an info from opkg command info or status from a package via keywords as std::string * 1st parameter is name of package as string eg. "gdb", without file extension or version data * 2nd parameter needs a keyword like: @@ -125,7 +128,25 @@ class COPKGManager : public CMenuTarget void showMenuConfigFeed(CMenuWidget *feed_menu); void updateMenu(); void refreshMenu(); + + //!Returns a vector with possible filter entries from OPKG_BAD_PATTERN_LIST_FILE + static std::vector getBadPackagePatternList(); + /*! + * Returns true if found a ''bad'' package, Parameter: package name as std::string by rev + * To detect bad packages, it must be exist a matching pattern list file. + * Path is defined in OPKG_BAD_PATTERN_LIST_FILE. + * This provides the option to filter some unwanted entries in the package list menue. + * This makes sense eg. to hinder that the user could change important system packages. + * NOTE: a sample file you should find here as : "/var/tuxbox/config/bad_package_pattern.list.sample" + * If required, remove the ".sample" extension and change the entries for your requirements + * howto: a simple way to filter a package is to add the pure name, if you want + * to hide a package (even which name) then add this name to a line. Eg. if you want to hide + * package wget then add this and this package is not displayed at the gui. + * Also a few place holders should work, see the badpackage() function, but this + * can be inaccurately because it could filter innocent packages. + */ bool badpackage(std::string &s); + void showError(const char* local_msg, char* err_msg = NULL, const std::string& additional_text = std::string()); int doUpdate(); void handleShellOutput(std::string* cur_line, int* res, bool* ok); From 4f9a3df6c4a0fbb7fd418cd1a95a99f3e89a642f Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Thu, 11 Jun 2015 11:36:05 +0200 Subject: [PATCH 108/110] COPKGManager: lets see user install result in window --- src/gui/opkg_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 2c1542481..a954d549b 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -819,7 +819,7 @@ bool COPKGManager::installPackage(const string& pkg_name, string options, bool f else{ string opts = " " + options + " "; - int r = execCmd(pkg_types[OM_INSTALL] + opts + pkg_name, CShellWindow::VERBOSE | CShellWindow::ACKNOWLEDGE_EVENT); + int r = execCmd(pkg_types[OM_INSTALL] + opts + pkg_name, CShellWindow::VERBOSE | CShellWindow::ACKNOWLEDGE_EVENT | CShellWindow::ACKNOWLEDGE); if (r){ switch(r){ case OM_OUT_OF_SPACE_ERR: From a9c549d0bf0fa20d4d1b1b817cc0b8d18cf4845c Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 28 Dec 2015 14:00:15 +0100 Subject: [PATCH 109/110] opkg_manager.cpp: add statement for local environment TODO: detect available opkg binary --- src/gui/opkg_manager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index a954d549b..6dacd4ca8 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -57,7 +57,12 @@ #include #include +#if 0 #define OPKG_CL "opkg" +#else +#define OPKG_CL "opkg-cl" +#endif + #define OPKG_TMP_DIR "/tmp/.opkg" #define OPKG_TEST_DIR OPKG_TMP_DIR "/test" #define OPKG_CL_CONFIG_OPTIONS " -V2 --tmp-dir=/tmp --cache=" OPKG_TMP_DIR From 92b579b3c625fef74e451a9dd73027efc0274c18 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Mon, 28 Dec 2015 14:06:03 +0100 Subject: [PATCH 110/110] opkg_manager.cpp: disable unused variable avoid compiler error/warning --- src/gui/opkg_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 6dacd4ca8..eb954d4c6 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -701,7 +701,7 @@ int COPKGManager::execCmd(const char *cmdstr, int verbose_mode) int res = 0; has_err = false; tmp_str.clear(); - bool ok = true; + //bool ok = true; //create CShellWindow object CShellWindow shell(cmd, verbose_mode, &res, false);