diff options
Diffstat (limited to 'displaymenu.c')
-rw-r--r-- | displaymenu.c | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/displaymenu.c b/displaymenu.c new file mode 100644 index 00000000..1cecf368 --- /dev/null +++ b/displaymenu.c @@ -0,0 +1,423 @@ +#include "displaymenu.h" + +cFlatDisplayMenu::cFlatDisplayMenu(void) { + CreateFullOsd(); + TopBarCreate(); + ButtonsCreate(); + MessageCreate(); + + VideoDiskUsageState = -1; + + itemHeight = fontHeight + Config.MenuItemPadding + Config.decorBorderMenuItemSize*2; + itemChannelHeight = fontHeight + Config.MenuItemPadding + Config.decorBorderMenuItemSize*2; + + scrollBarWidth = ScrollBarWidth() + Config.MenuItemPadding; + scrollBarHeight = osdHeight - (topBarHeight + Config.decorBorderTopBarSize*2 + + buttonsHeight + Config.decorBorderButtonSize*2 + marginItem*3 ); + scrollBarTop = topBarHeight + marginItem + Config.decorBorderTopBarSize*2; + + menuWidth = osdWidth - scrollBarWidth; + menuTop = topBarHeight + marginItem + Config.decorBorderTopBarSize*2 + Config.decorBorderMenuItemSize; + menuPixmap = osd->CreatePixmap(1, cRect(0, menuTop, menuWidth, scrollBarHeight )); + + chLeft = Config.decorBorderMenuContentHeadSize; + chTop = topBarHeight + marginItem + Config.decorBorderTopBarSize*2 + Config.decorBorderMenuContentHeadSize; + chWidth = menuWidth - Config.decorBorderMenuContentHeadSize*2; + chHeight = fontHeight + fontSmlHeight*2 + marginItem*2; + contentHeadPixmap = osd->CreatePixmap(1, cRect(chLeft, chTop, chWidth, chHeight)); + + cLeft = Config.decorBorderMenuContentSize; + cTop = chTop + marginItem*3 + fontHeight + fontSmlHeight*2 + + Config.decorBorderMenuContentSize + Config.decorBorderMenuContentHeadSize; + cWidth = menuWidth - Config.decorBorderMenuContentSize*2; + cHeight = osdHeight - (topBarHeight + Config.decorBorderTopBarSize*2 + + buttonsHeight + Config.decorBorderButtonSize*2 + marginItem*3 + + chHeight + Config.decorBorderMenuContentHeadSize*2 + Config.decorBorderMenuContentSize*2); + ContentCreate(cLeft, cTop, cWidth, cHeight); + + scrollbarPixmap = osd->CreatePixmap(2, cRect(osdWidth - scrollBarWidth, scrollBarTop, scrollBarWidth, scrollBarHeight)); + + menuPixmap->Fill(clrTransparent); + scrollbarPixmap->Fill(clrTransparent); + + menuCategory = mcUndefined; +} + +cFlatDisplayMenu::~cFlatDisplayMenu() { + osd->DestroyPixmap(menuPixmap); + osd->DestroyPixmap(scrollbarPixmap); + osd->DestroyPixmap(contentHeadPixmap); +} + +void cFlatDisplayMenu::SetMenuCategory(eMenuCategory MenuCategory) { + menuCategory = MenuCategory; +} + +void cFlatDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown) { + ScrollbarDraw(scrollbarPixmap, Config.MenuItemPadding, Top, Height, Total, Offset, Shown, CanScrollUp, CanScrollDown); +} + +void cFlatDisplayMenu::SetScrollbar(int Total, int Offset) { + DrawScrollbar(Total, Offset, MaxItems(), 0, ItemsHeight(), Offset > 0, Offset + MaxItems() < Total); +} + +void cFlatDisplayMenu::Scroll(bool Up, bool Page) { + // Wird das Menü gescrollt oder Content? + if( ContentIsShown() ) + { + bool scrolled = ContentScroll(Up, Page); + if( scrolled ) + { + DrawScrollbar(ContentScrollTotal(), ContentScrollOffset(), ContentVisibleLines(), contentTop - scrollBarTop, ContentGetHeight(), ContentScrollOffset() > 0, ContentScrollOffset() + ContentVisibleLines() < ContentScrollTotal()); + } + } else { + cSkinDisplayMenu::Scroll(Up, Page); + } +} + +int cFlatDisplayMenu::MaxItems(void) { + if( menuCategory == mcChannel ) + return scrollBarHeight / itemChannelHeight; + + return scrollBarHeight / itemHeight; +} + +int cFlatDisplayMenu::ItemsHeight(void) { + if( menuCategory == mcChannel ) + return MaxItems() * itemChannelHeight - Config.MenuItemPadding; + + return MaxItems() * itemHeight - Config.MenuItemPadding; +} + +void cFlatDisplayMenu::Clear(void) { + textScroller.Reset(); + menuPixmap->Fill(clrTransparent); + scrollbarPixmap->Fill(clrTransparent); + contentHeadPixmap->Fill(clrTransparent); + ContentClear(); + DecorBorderClearAll(); + // DecorBorderClearByFrom( BorderMenuItem ); +} + +void cFlatDisplayMenu::SetTitle(const char *Title) { + if( (menuCategory == mcRecording || menuCategory == mcTimer) && Config.DiskUsageShow ) { + cVideoDiskUsage::HasChanged(VideoDiskUsageState); + int DiskUsage = cVideoDiskUsage::UsedPercent(); + int FreeGB = cVideoDiskUsage::FreeMB() / 1024; + cString extra1 = cString::sprintf("%s: %d%%", tr("disk usage"), DiskUsage); + cString extra2 = cString::sprintf("%s: %d GB", tr("free space"), FreeGB); + + cString iconName("chart1"); + if( DiskUsage > 14 ) + iconName = "chart2"; + if( DiskUsage > 28 ) + iconName = "chart3"; + if( DiskUsage > 42 ) + iconName = "chart4"; + if( DiskUsage > 56 ) + iconName = "chart5"; + if( DiskUsage > 70 ) + iconName = "chart6"; + if( DiskUsage > 84 ) + iconName = "chart7"; + + TopBarSetTitle(Title); + TopBarSetTitleExtra(extra1, extra2); + TopBarSetExtraIcon(iconName); + } else + TopBarSetTitle(Title); +} + +void cFlatDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) { + ButtonsSet(Red, Green, Yellow, Blue); +} + +void cFlatDisplayMenu::SetMessage(eMessageType Type, const char *Text) { + if (Text) + MessageSet(Type, Text); + else + MessageClear(); +} + +void cFlatDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable) { + int y = Index * itemHeight; + tColor ColorFg, ColorBg; + if (Current) { + ColorFg = Theme.Color(clrItemCurrentFont); + ColorBg = Theme.Color(clrItemCurrentBg); + } + else { + if( Selectable ) { + ColorFg = Theme.Color(clrItemSelableFont); + ColorBg = Theme.Color(clrItemSelableBg); + } else { + ColorFg = Theme.Color(clrItemFont); + ColorBg = Theme.Color(clrItemBg); + } + } + + for (int i = 0; i < MaxTabs; i++) + { + const char *s = GetTabbedText(Text, i); + if (s) { + int xt = Tab(i); + if( CheckProgressBar( s ) ) { + int colWidth = Tab(i+1) - Tab(i); + + tColor ColorFg = Config.decorProgressMenuItemFg; + tColor ColorBarFg = Config.decorProgressMenuItemBarFg; + tColor ColorBg = Config.decorProgressMenuItemBg; + if( Current ) { + ColorFg = Config.decorProgressMenuItemCurFg; + ColorBarFg = Config.decorProgressMenuItemCurBarFg; + ColorBg = Config.decorProgressMenuItemCurBg; + } + DrawProgressBarFromText(y + (itemHeight-Config.MenuItemPadding)/2 - Config.decorProgressMenuItemSize/2 - Config.decorBorderMenuItemSize, + xt + Config.decorBorderMenuItemSize, colWidth, s, ColorFg, ColorBarFg, ColorBg); + } else { + menuPixmap->DrawText(cPoint(xt + Config.decorBorderMenuItemSize, y), s, ColorFg, ColorBg, font, + menuWidth - Config.decorBorderMenuItemSize*2 - xt); + } + } + if (!Tab(i + 1)) + break; + } + + int left = Config.decorBorderMenuItemSize; + int top = topBarHeight + marginItem + Config.decorBorderTopBarSize*2 + Config.decorBorderMenuItemSize + y; + + if( Current ) + DecorBorderDraw(left, top, menuWidth - Config.decorBorderMenuItemSize*2, fontHeight, + Config.decorBorderMenuItemSize, Config.decorBorderMenuItemType, Config.decorBorderMenuItemCurFg, + Config.decorBorderMenuItemCurBg, BorderMenuItem); + else { + if( Selectable ) + DecorBorderDraw(left, top, menuWidth - Config.decorBorderMenuItemSize*2, fontHeight, + Config.decorBorderMenuItemSize, Config.decorBorderMenuItemType, Config.decorBorderMenuItemSelFg, + Config.decorBorderMenuItemSelBg, BorderMenuItem); + else + DecorBorderDraw(left, top, menuWidth - Config.decorBorderMenuItemSize*2, fontHeight, + Config.decorBorderMenuItemSize, Config.decorBorderMenuItemType, Config.decorBorderMenuItemFg, + Config.decorBorderMenuItemBg, BorderMenuItem); + } + + SetEditableWidth(menuWidth - Tab(1)); +} + +bool cFlatDisplayMenu::CheckProgressBar(const char *text) { + if (strlen(text) > 5 + && text[0] == '[' + && ((text[1] == '|')||(text[1] == ' ')) + && ((text[2] == '|')||(text[2] == ' ')) + && text[strlen(text) - 1] == ']') + return true; + return false; +} + +void cFlatDisplayMenu::DrawProgressBarFromText(int Top, int Left, int Width, const char *bar, tColor ColorFg, tColor ColorBarFg, tColor ColorBg) { + const char *p = bar + 1; + bool isProgressbar = true; + int total = 0; + int now = 0; + for (; *p != ']'; ++p) { + if (*p == ' ' || *p == '|') { + ++total; + if (*p == '|') + ++now; + } else { + isProgressbar = false; + break; + } + } + if (isProgressbar) { + double progress = (double)now/(double)total; + ProgressBarDrawRaw(menuPixmap, menuPixmap, cRect(Left, Top, Width, Config.decorProgressMenuItemSize), + cRect(Left, Top, Width, Config.decorProgressMenuItemSize), progress*total, total, + ColorFg, ColorBarFg, ColorBg, Config.decorProgressMenuItemType); + } +} + +/* +bool cFlatDisplayMenu::SetItemChannel(const cChannel *Channel, int Index, bool Current, bool Selectable, bool WithProvider) { + cSchedulesLock schedulesLock; + const cSchedules *schedules = cSchedules::Schedules(schedulesLock); + + cString buffer; + int y = Index * itemChannelHeight; + + tColor ColorFg, ColorBg; + if (Current) { + ColorFg = Theme.Color(clrItemCurrentFont); + ColorBg = Theme.Color(clrItemCurrentBg); + } + else { + if( Selectable ) { + ColorFg = Theme.Color(clrItemSelableFont); + ColorBg = Theme.Color(clrItemSelableBg); + } else { + ColorFg = Theme.Color(clrItemFont); + ColorBg = Theme.Color(clrItemBg); + } + } + menuPixmap->DrawRectangle(cRect(0, y, menuWidth, itemChannelHeight - paddingMenuItem), ColorBg); + + // event from channel + const cSchedule *Schedule = schedules->GetSchedule( Channel->GetChannelID() ); + if( Schedule ) { + const cEvent *Event = Schedule->GetPresentEvent(); + if( Event ) { + // calculate progress bar + float progress = (int)roundf( (float)(time(NULL) - Event->StartTime()) / (float) (Event->Duration()) * 100.0); + if(progress < 0) + progress = 0.; + else if(progress > 100) + progress = 100; + + if( WithProvider ) + buffer = cString::sprintf("%d\t%s - %s", Channel->Number(), Channel->Provider(), Channel->Name()); + else + buffer = cString::sprintf("%d\t%s", Channel->Number(), Channel->Name()); + + const char *s1 = GetTabbedText(buffer, 0); + if( s1 ) { + int xt = Tab(0); + menuPixmap->DrawText(cPoint(marginItem + xt, y), s1, ColorFg, ColorBg, font); + } + const char *s2 = GetTabbedText(buffer, 1); + if( s2 ) { + int xt = Tab(1); + int w = (menuWidth / 10 * 3) - marginItem; + menuPixmap->DrawText(cPoint(marginItem + xt, y), s2, ColorFg, ColorBg, font, w); + } + + menuPixmap->DrawRectangle(cRect( (menuWidth/10*3) + marginItem, y, marginItem, fontHeight), ColorBg); + + if( Current ) + ProgressBarDrawInline(menuPixmap, (menuWidth/10*3) + marginItem*2, y, menuWidth/10 - marginItem, fontHeight, + progress, 100, Theme.Color(clrMenuItemChanCurProgressFg), Theme.Color(clrMenuItemChanCurProgressBarFg), + Theme.Color(clrMenuItemChanCurProgressBg)); + else + ProgressBarDrawInline(menuPixmap, (menuWidth/10*3) + marginItem*2, y, menuWidth/10 - marginItem, fontHeight, + progress, 100, Theme.Color(clrMenuItemChanProgressFg), Theme.Color(clrMenuItemChanProgressBarFg), + Theme.Color(clrMenuItemChanProgressBg)); + menuPixmap->DrawText(cPoint((menuWidth / 10 * 4) + marginItem*2, y), Event->Title(), ColorFg, ColorBg, font); + + return true; + } + } + + // without schedule, do it like vdr + if (!Channel->GroupSep()) { + if( WithProvider ) + buffer = cString::sprintf("%d\t%s - %s", Channel->Number(), Channel->Provider(), Channel->Name()); + else + buffer = cString::sprintf("%d\t%s", Channel->Number(), Channel->Name()); + + const char *s1 = GetTabbedText(buffer, 0); + if( s1 ) { + int xt = Tab(0); + menuPixmap->DrawText(cPoint(marginItem + xt, y), s1, ColorFg, ColorBg, font); + } + const char *s2 = GetTabbedText(buffer, 1); + if( s2 ) { + int xt = Tab(1); + int w = (menuWidth / 10 * 3) - marginItem; + + menuPixmap->DrawText(cPoint(marginItem + xt, y), s2, ColorFg, ColorBg, font, w); + } + } + else { + buffer = cString::sprintf("---%s ----------------------------------------------------------------", Channel->Name()); + menuPixmap->DrawText(cPoint(marginItem, y), buffer, ColorFg, ColorBg, font); + } + + return true; +} +*/ + +void cFlatDisplayMenu::SetEvent(const cEvent *Event) { + if( !Event ) + return; + + contentHeadPixmap->Fill(clrTransparent); + contentHeadPixmap->DrawRectangle(cRect(0, 0, menuWidth, fontHeight + fontSmlHeight*2 + marginItem*2), Theme.Color(clrScrollbarBg)); + + cString date = Event->GetDateString(); + cString startTime = Event->GetTimeString(); + cString endTime = Event->GetEndTimeString(); + + cString timeString = cString::sprintf("%s %s - %s", *date, *startTime, *endTime); + + cString title = Event->Title(); + cString shortText = Event->ShortText(); + + contentHeadPixmap->DrawText(cPoint(marginItem, marginItem), timeString, Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontSml, menuWidth - marginItem*2); + contentHeadPixmap->DrawText(cPoint(marginItem, marginItem + fontSmlHeight), title, Theme.Color(clrMenuEventFontTitle), Theme.Color(clrMenuEventBg), font, menuWidth - marginItem*2); + contentHeadPixmap->DrawText(cPoint(marginItem, marginItem + fontSmlHeight + fontHeight), shortText, Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontSml, menuWidth - marginItem*2); + + DecorBorderDraw(chLeft, chTop, chWidth, chHeight, Config.decorBorderMenuContentHeadSize, Config.decorBorderMenuContentHeadType, + Config.decorBorderMenuContentHeadFg, Config.decorBorderMenuContentHeadBg); + + ContentSet( Event->Description(), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg) ); + if( ContentScrollable() ) + DrawScrollbar(ContentScrollTotal(), ContentScrollOffset(), ContentVisibleLines(), contentTop - scrollBarTop, ContentGetHeight(), ContentScrollOffset() > 0, ContentScrollOffset() + ContentVisibleLines() < ContentScrollTotal()); + + DecorBorderDraw(cLeft, cTop, cWidth, ContentGetHeight(), Config.decorBorderMenuContentSize, Config.decorBorderMenuContentType, + Config.decorBorderMenuContentFg, Config.decorBorderMenuContentBg); +} + +void cFlatDisplayMenu::SetRecording(const cRecording *Recording) { + if( !Recording ) + return; + contentHeadPixmap->Fill(clrTransparent); + contentHeadPixmap->DrawRectangle(cRect(0, 0, menuWidth, fontHeight + fontSmlHeight*2 + marginItem*2), Theme.Color(clrScrollbarBg)); + + const cRecordingInfo *recInfo = Recording->Info(); + cString timeString = cString::sprintf("%s %s %s", *DateString(Recording->Start()), *TimeString(Recording->Start()), recInfo->ChannelName() ? recInfo->ChannelName() : ""); + + cString title = recInfo->Title(); + if( isempty(title) ) + title = Recording->Name(); + cString shortText = recInfo->ShortText(); + + contentHeadPixmap->DrawText(cPoint(marginItem, marginItem), timeString, Theme.Color(clrMenuRecFontInfo), Theme.Color(clrMenuRecBg), fontSml, menuWidth - marginItem*2); + contentHeadPixmap->DrawText(cPoint(marginItem, marginItem + fontSmlHeight), title, Theme.Color(clrMenuRecFontTitle), Theme.Color(clrMenuRecBg), font, menuWidth - marginItem*2); + contentHeadPixmap->DrawText(cPoint(marginItem, marginItem + fontSmlHeight + fontHeight), shortText, Theme.Color(clrMenuRecFontInfo), Theme.Color(clrMenuRecBg), fontSml, menuWidth - marginItem*2); + + DecorBorderDraw(chLeft, chTop, chWidth, chHeight, Config.decorBorderMenuContentHeadSize, Config.decorBorderMenuContentHeadType, + Config.decorBorderMenuContentHeadFg, Config.decorBorderMenuContentHeadBg); + + ContentSet( recInfo->Description(), Theme.Color(clrMenuRecFontInfo), Theme.Color(clrMenuRecBg) ); + if( ContentScrollable() ) + DrawScrollbar(ContentScrollTotal(), ContentScrollOffset(), ContentVisibleLines(), contentTop - scrollBarTop, ContentGetHeight(), ContentScrollOffset() > 0, ContentScrollOffset() + ContentVisibleLines() < ContentScrollTotal()); + + DecorBorderDraw(cLeft, cTop, cWidth, ContentGetHeight(), Config.decorBorderMenuContentSize, Config.decorBorderMenuContentType, + Config.decorBorderMenuContentFg, Config.decorBorderMenuContentBg); +} + +void cFlatDisplayMenu::SetText(const char *Text, bool FixedFont) { + if( !Text ) + return; + contentHeadPixmap->Fill(clrTransparent); + + ContentSet( Text, Theme.Color(clrMenuTextFont), Theme.Color(clrMenuTextBg) ); + if( ContentScrollable() ) + SetScrollbar( ContentScrollTotal(), 0 ); + + DecorBorderDraw(cLeft, cTop, cWidth, ContentGetHeight(), Config.decorBorderMenuContentSize, Config.decorBorderMenuContentType, + Config.decorBorderMenuContentFg, Config.decorBorderMenuContentBg); +} + +int cFlatDisplayMenu::GetTextAreaWidth(void) const { + return menuWidth - (marginItem*2); +} + +const cFont *cFlatDisplayMenu::GetTextAreaFont(bool FixedFont) const { + const cFont *rfont = FixedFont ? fontFixed : font; + return rfont; +} + +void cFlatDisplayMenu::Flush(void) { + TopBarUpdate(); + osd->Flush(); +} |