diff options
author | kamel5 <vdr.kamel5 (at) gmx (dot) net> | 2021-04-16 14:19:03 +0200 |
---|---|---|
committer | kamel5 <vdr.kamel5 (at) gmx (dot) net> | 2021-04-22 15:14:05 +0200 |
commit | 46c28206c4ee946acfd05596053bf03366808671 (patch) | |
tree | bb9401f2b55042be0168556b2e23f0ff0160d100 /displaymenu.c | |
parent | 0c9b9ff2bcd461496da502cb63e53209d9d6ce74 (diff) | |
download | skin-lcarsng-46c28206c4ee946acfd05596053bf03366808671.tar.gz skin-lcarsng-46c28206c4ee946acfd05596053bf03366808671.tar.bz2 |
Automatic display description in menu epg, timer and recording
Diffstat (limited to 'displaymenu.c')
-rw-r--r-- | displaymenu.c | 295 |
1 files changed, 293 insertions, 2 deletions
diff --git a/displaymenu.c b/displaymenu.c index ab1cd0d..87f5d13 100644 --- a/displaymenu.c +++ b/displaymenu.c @@ -15,6 +15,7 @@ cLCARSNGDisplayMenu::cLCARSNGDisplayMenu(void) { tallFont = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize * 1.6); initial = true; + message = false; viewmode = efullscreen; zoom = 0; lastMode = cmUnknown; @@ -47,6 +48,7 @@ cLCARSNGDisplayMenu::cLCARSNGDisplayMenu(void) textColorBg = Theme.Color(clrMenuTextBg); currentIndex = -1; Margin = Config.Margin; + drawDescription = NULL; // The outer frame: d = 5 * lineHeight; @@ -85,6 +87,7 @@ cLCARSNGDisplayMenu::cLCARSNGDisplayMenu(void) cLCARSNGDisplayMenu::~cLCARSNGDisplayMenu() { + delete drawDescription; delete tallFont; delete tinyFont; delete osd; @@ -321,7 +324,6 @@ void cLCARSNGDisplayMenu::SetMenuCategory(eMenuCategory MenuCategory) default: viewmode = Config.mcDefaultScaled; } - if (MenuCategory == mcChannel && viewmode == esmalscreen) { SetCoordinateY(yt06); osd->DrawRectangle(xa00, yt00, xa09 - 1, yb15 - 1, clrTransparent); @@ -1249,6 +1251,11 @@ int cLCARSNGDisplayMenu::MaxItems(void) void cLCARSNGDisplayMenu::Clear(void) { + DELETENULL(drawDescription); + animatedInfo.Event = NULL; + animatedInfo.Timer = NULL; + animatedInfo.Recording = NULL; + animatedInfo.Channel = NULL; textScroller.Reset(); osd->DrawRectangle(xi00, yi00, xi03 - 1, yi01 - 1, Theme.Color(clrBackground)); } @@ -1305,6 +1312,8 @@ void cLCARSNGDisplayMenu::SetButtons(const char *Red, const char *Green, const c void cLCARSNGDisplayMenu::SetMessage(eMessageType Type, const char *Text) { if (Text) { + DELETENULL(drawDescription); + message = true; tColor ColorFg = Theme.Color(clrMessageStatusFg + 2 * Type); tColor ColorBg = Theme.Color(clrMessageStatusBg + 2 * Type); int x0, x1, y0, y1, lx, ly; @@ -1318,8 +1327,61 @@ void cLCARSNGDisplayMenu::SetMessage(eMessageType Type, const char *Text) DrawRectangleOutline(osd, x0, y0, x1, y1, ColorFg, ColorBg, 15); osd->DrawText(x0 + Margin, y0 + Margin, Text, ColorFg, ColorBg, cFont::GetFont(fontSml), lx, ly, taCenter); } - else + else { osd->RestoreRegion(); + message = false; + } +} +bool cLCARSNGDisplayMenu::SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch, bool TimerActive) +{ + if (animatedInfo.Event == Event && !Current) { + DELETENULL(drawDescription); + animatedInfo.Event = NULL; + } + if (Current) { + animatedInfo.Event = Event; + animatedInfo.Index = Index; + animatedInfo.Current = Current; + animatedInfo.Selectable = Selectable; + animatedInfo.Channel = Channel; + animatedInfo.WithDate = WithDate; + animatedInfo.TimerMatch = TimerMatch; + animatedInfo.TimerActive = TimerActive; + } + return false; +} + +bool cLCARSNGDisplayMenu::SetItemTimer(const cTimer *Timer, int Index, bool Current, bool Selectable) +{ + if (animatedInfo.Timer == Timer && !Current) { + DELETENULL(drawDescription); + animatedInfo.Timer = NULL; + } + if (Current) { + animatedInfo.Timer = Timer; + animatedInfo.Index = Index; + animatedInfo.Current = Current; + animatedInfo.Selectable = Selectable; + } + return false; +} + +bool cLCARSNGDisplayMenu::SetItemRecording(const cRecording *Recording, int Index, bool Current, bool Selectable, int Level, int Total, int New) +{ + if (animatedInfo.Recording == Recording && !Current) { + DELETENULL(drawDescription); + animatedInfo.Recording = NULL; + } + if (Current && !Total) { + animatedInfo.Recording = Recording; + animatedInfo.Index = Index; + animatedInfo.Current = Current; + animatedInfo.Selectable = Selectable; + animatedInfo.Level = Level; + animatedInfo.Total = Total; + animatedInfo.New = New; + } + return false; } void cLCARSNGDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable) @@ -1491,6 +1553,9 @@ void cLCARSNGDisplayMenu::Flush(void) else availableRect = cDevice::PrimaryDevice()->CanScaleVideo(cRect::Null); } + if (drawDescription) { + drawDescription->StopFlush(); + } DrawFrameDisplay(); switch (MenuCategory()) { case mcMain: @@ -1527,5 +1592,231 @@ void cLCARSNGDisplayMenu::Flush(void) if (initial) { cDevice::PrimaryDevice()->ScaleVideo(availableRect); } + if (!message && !drawDescription) { + if ((Config.displInfoMenuEPG && (MenuCategory() == mcSchedule || MenuCategory() == mcScheduleNow || MenuCategory() == mcScheduleNext) && animatedInfo.Event != NULL) + || (Config.displInfoMenuTimer && MenuCategory() == mcTimer && animatedInfo.Timer != NULL) + || (Config.displInfoMenuRec && MenuCategory() == mcRecording && animatedInfo.Recording != NULL)) { + animatedInfo.x0 = xs00; + animatedInfo.x1 = xs11; + animatedInfo.y0 = yi00; + animatedInfo.y1 = yi00 + (int)((yi01 - yi00) / lineHeight) * lineHeight; + animatedInfo.viewmode = viewmode; + animatedInfo.textColorBg = textColorBg; + animatedInfo.titleColorFg = Theme.Color(clrEventTitle); + animatedInfo.shortTextColorFg = Theme.Color(clrEventShortText); + animatedInfo.descriptionColorFg = Theme.Color(clrEventDescription); + animatedInfo.frameColorBr = frameColorBr; + drawDescription = new cDrawDescription(osd, animatedInfo); + } + } + if (drawDescription) { + drawDescription->StartFlush(); + } initial = false; } + +// --- cDrawDescription ---------------------------------------------------- + +cDrawDescription::cDrawDescription(cOsd *osd, AnimatedInfo_t animatedInfo) : cThread("LCARS DisplDesc") +{ + this->osd = osd; + aI = animatedInfo; + lineHeight = cFont::GetFont(fontSml)->Height(); + + Start(); +} + +cDrawDescription::~cDrawDescription() +{ + isAnimated = true; + Cancel(2); + if (ScrollPixmap) + osd->DestroyPixmap(ScrollPixmap); + if (BracketPixmap) + osd->DestroyPixmap(BracketPixmap); + if (BackgroundPixmap) + osd->DestroyPixmap(BackgroundPixmap); +} + +void cDrawDescription::DrawBracket(void) +{ + int x0 = aI.x0; + int x1 = aI.x1; + int y0 = aI.y0; + int y1 = aI.y1; + BackgroundPixmap = osd->CreatePixmap(-1, cRect(x0, y0, x1 - x0, y1 - y0)); + BackgroundPixmap->SetAlpha(0); + BackgroundPixmap->Fill((aI.viewmode == escaledvideo) ? Theme.Color(clrBackground) : aI.textColorBg); + BracketPixmap = osd->CreatePixmap(-1, cRect(x0, y0, x1 - x0, y1 - y0)); + BracketPixmap->SetAlpha(0); + BracketPixmap->Fill(clrTransparent); + tColor Color = Theme.Color(clrMenuMainBracket); + int lineHeight = cFont::GetFont(fontOsd)->Height("A"); + int x00, x01, x02, y00, y01, y02, y03, y04; + x00 = 0; + x01 = x00 + lineHeight; + x02 = x1 - x01; + y00 = 0; + y01 = y00 + lineHeight / 2; + y02 = y01 + lineHeight / 2; + y04 = y1 - y0; + y03 = y04 - lineHeight; + BracketPixmap->DrawRectangle(cRect(x01, y00, x02, lineHeight / 2), Color); + BracketPixmap->DrawEllipse (cRect(x00, y00, lineHeight, y02), Color, 2); + BracketPixmap->DrawEllipse (cRect(x01, y01, lineHeight / 2, lineHeight / 2), Color, -2); + BracketPixmap->DrawRectangle(cRect(x00, y02, lineHeight, y03 - y02), Color); + BracketPixmap->DrawEllipse (cRect(x00, y03, lineHeight, lineHeight), Color, 3); + BracketPixmap->DrawEllipse (cRect(x01, y03, lineHeight / 2, lineHeight / 2), Color, -3); + BracketPixmap->DrawRectangle(cRect(x01, y04 - lineHeight / 2, x02, lineHeight / 2), Color); +} + +void cDrawDescription::Draw(void) +{ + const cEvent *Event = NULL; + const cTimer *Timer = NULL; + const cRecording *Recording = NULL; + const cRecordingInfo *Info = NULL; + + if (aI.Recording) { + Recording = aI.Recording; + Info = Recording->Info(); + if (!Info->Description()) + return; + } else if (aI.Event) { + Event = aI.Event; + if (!Event->Description()) + return; + } else if (aI.Timer) { + Timer = aI.Timer; + Event = Timer->Event(); + if (!Event->Description()) + return; + } else + return; + + const char *titel = NULL; + const char *shortText = NULL; + const char *s = NULL; + const cFont *Font = cFont::GetFont(fontSml); + BackgroundPixmap->SetAlpha(0); + BracketPixmap->SetAlpha(0); + tColor textColorBg = clrTransparent; + + if (Recording) { + s = Info->Description(); // text + titel = Info->ChannelName(); + shortText = Info->ShortText(); + } + else { + s = Event->Description(); // text + titel = Event->Title(); + shortText = Event->ShortText(); + } + int x0 = aI.x0 + 1.5 * lineHeight; // text left + int x1 = aI.x1; // text right + int y0 = aI.y0 + 1.3 * lineHeight; // text top + int y1 = aI.y1 - 1.3 * lineHeight; // text bottom + + int textwidth = x1 - x0 - lineHeight / 2; + + int x00 = 1.5 * lineHeight; + int y00 = 1.3 * lineHeight; + if (!isempty(titel)) { + BracketPixmap->DrawText(cPoint(x00 + Config.Margin + Gap, y00), titel, aI.titleColorFg, textColorBg, Font, textwidth); // title + y00 = y00 + 1.3 * lineHeight; + y0 = y0 + 1.3 * lineHeight; + } + + if (!isempty(shortText)) { + BracketPixmap->DrawText(cPoint(x00 + Config.Margin + Gap, y00), shortText, aI.shortTextColorFg, textColorBg, Font, textwidth); // shorttext + y0 = y0 + 1.3 * lineHeight; + } + + y0 = y0 + 0.4 * lineHeight; + + wrapper.Set(s, Font, textwidth); + int l0 = wrapper.Lines(); // textlines + + int height = y1 - y0; // max height + int lines = (int)(height / lineHeight); // visible lines + + int l1 = min(l0, lines); // visible textlines -> scrollwindow + + int pixmapwidth = x1 - x0; + int pixmapHeigh = l1 * lineHeight; + ScrollPixmap = osd->CreatePixmap(-1, cRect(x0, y0, pixmapwidth, pixmapHeigh), cRect(0, 0, pixmapwidth, l0 * lineHeight)); + ScrollPixmap->Lock(); + ScrollPixmap->Fill(clrTransparent); + ScrollPixmap->SetAlpha(0); + + for (int i = 0; i < l0; i++) { + ScrollPixmap->DrawText(cPoint(Config.Margin + Gap, i * lineHeight), wrapper.GetLine(i), aI.descriptionColorFg, textColorBg, Font, textwidth); // description + } + + ScrollPixmap->Unlock(); + MoveStart = ScrollPixmap->DrawPort().Point(); + + int h0 = l0 * lineHeight; // text height in pixel + int y = (pixmapHeigh - h0); // pixel to scroll + + MoveEnd.Set(0, min(0, y)); + isAnimated = false; +} + +void cDrawDescription::Action(void) +{ + DrawBracket(); + Draw(); + if (isAnimated) + return; + + bool faded = false; + int j = 0; + int y = Config.scrollPixel; + int z = 0; + int step = (Config.fadeinTime) ? (255 * Config.framesPerSecond / Config.fadeinTime) : 255; + uint64_t Now; + uint64_t StartTime = cTimeMs::Now(); + + while (Running()) { + Now = cTimeMs::Now(); + if ((int)(Now - StartTime) > Config.waitTimeFadein) { + if (ScrollPixmap && !isAnimated) { + if (!faded) { + BackgroundPixmap->SetLayer(0); + BracketPixmap->SetLayer(1); + ScrollPixmap->SetLayer(2); + z = z + step; + if (z <= (255 + step)) { + int alpha = min(z, 255); + BackgroundPixmap->SetAlpha(alpha); + BracketPixmap->SetAlpha(alpha); + ScrollPixmap->SetAlpha(alpha); + } else { + faded = true; + StartTime = cTimeMs::Now(); + } + } + if (faded && (int)(Now - StartTime) > Config.waitTimeScroll) { + if (j <= MoveEnd.Y()) { + isAnimated = true; + } else { + ScrollPixmap->Scroll(cPoint(0, -y)); + j = j - y; + } + } + } + } + int count = 0; + while (!isAnimated && !doflush && count < 200) { + cCondWait::SleepMs(10); + count++; + } + if (osd) + osd->Flush(); + if (isAnimated) + break; + int Rest = (int)(1000 / Config.framesPerSecond) - ((int)(cTimeMs::Now() - Now)); + cCondWait::SleepMs(max(2, Rest)); + } +} |