summaryrefslogtreecommitdiff
path: root/displaymenu.c
diff options
context:
space:
mode:
Diffstat (limited to 'displaymenu.c')
-rw-r--r--displaymenu.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/displaymenu.c b/displaymenu.c
new file mode 100644
index 0000000..ea1a868
--- /dev/null
+++ b/displaymenu.c
@@ -0,0 +1,461 @@
+#include "displaymenu.h"
+#include <string>
+
+cNopacityDisplayMenu::cNopacityDisplayMenu(void) {
+ int start = cTimeMs::Now();
+ config.setDynamicValues();
+ menuCategoryLast = mcUndefined;
+ menuSubCategory = mcSubUndefined;
+ menuSubCategoryLast = mcSubUndefined;
+ FrameTime = config.menuFrameTime;
+ FadeTime = config.menuFadeTime;
+ initial = true;
+ initMenu = true;
+ diskUsageDrawn = false;
+ timersDrawn = false;
+ lastDiskUsageState = -1;
+ lastTimersState = -1;
+ menuItemIndexLast = -1;
+ currentNumItems = 0;
+ menuHasIcons = true;
+ detailView = NULL;
+ contentNarrow = true;
+ contentNarrowLast = true;
+ menuView = new cNopacityDisplayMenuView();
+ osd = menuView->createOsd();
+ menuView->SetGeometry();
+ menuView->CreatePixmaps();
+ menuView->CreateFonts();
+ menuView->SetAvrgFontWidth();
+ menuView->CreateBackgroundImages(handleBackgrounds, handleButtons);
+ menuView->DrawHeaderLogo();
+ menuView->DrawBorderDecoration();
+ dsyslog("nopacity: Construktor needed %d ms", int(cTimeMs::Now()-start));
+}
+
+cNopacityDisplayMenu::~cNopacityDisplayMenu() {
+ if (Running()) {
+ Cancel();
+ cCondWait::SleepMs(300);
+ }
+ delete menuView;
+ menuItems.Clear();
+ if (detailView) {
+ delete detailView;
+ }
+ timers.Clear();
+ for (int i=0; i<6; i++)
+ cOsdProvider::DropImage(handleBackgrounds[i]);
+ for (int i=0; i<4; i++)
+ cOsdProvider::DropImage(handleButtons[i]);
+
+ delete osd;
+}
+
+void cNopacityDisplayMenu::DrawDisk(void) {
+ if (initial || ((menuCategoryLast!=mcMain)&&(MenuCategory()==mcMain)&&!diskUsageDrawn)) {
+ if (cVideoDiskUsage::HasChanged(lastDiskUsageState)) {
+ menuView->DrawDiskUsage();
+ } else {
+ menuView->ShowDiskUsage(true);
+ }
+ diskUsageDrawn = true;
+ }
+}
+
+void cNopacityDisplayMenu::DrawTimers(void) {
+ int maxTimersHeight = menuView->GetTimersMaxHeight();
+ if (initial || ((menuCategoryLast!=mcMain)&&(MenuCategory()==mcMain)&&!timersDrawn)) {
+ if (Timers.Modified(lastTimersState)) {
+ timers.Clear();
+ cSortedTimers SortedTimers;
+ int numTimers = SortedTimers.Size();
+ int currentHeight = menuView->GetTimersInitHeight();
+ for (int i = 0; i < numTimers; i++) {
+ if (const cTimer *Timer = SortedTimers[i]) {
+ cNopacityTimer *t = menuView->DrawTimer(Timer, currentHeight);
+ if (initial)
+ if (FadeTime)
+ t->SetAlpha(0);
+ currentHeight += t->pixmap->ViewPort().Height() + menuView->spaceMenu;
+ if (currentHeight < maxTimersHeight) {
+ timers.Add(t);
+ } else {
+ delete t;
+ break;
+ }
+ }
+ }
+ } else {
+ for (cNopacityTimer *t = timers.First(); t; t = timers.Next(t)) {
+ t->SetLayer(2);
+ }
+ }
+ timersDrawn = true;
+ }
+}
+
+void cNopacityDisplayMenu::Scroll(bool Up, bool Page) {
+ bool scrolled;
+ scrolled = detailView->Scroll(Up, Page);
+ if (scrolled) {
+ double height = detailView->ScrollbarSize();
+ double offset = detailView->Offset();
+ menuView->DrawScrollbar(height, offset);
+ }
+}
+
+int cNopacityDisplayMenu::MaxItems(void) {
+ int maxItems = 0;
+ if (((MenuCategory() == mcChannel) && (menuSubCategory == mcSubChannelEdit) && (menuSubCategoryLast != mcSubChannelEdit))
+ || (menuSubCategory == mcSubScheduleTimer)){
+ maxItems = config.numDefaultMenuItems;
+ } else {
+ maxItems = menuView->GetMaxItems(MenuCategory());
+ }
+ currentNumItems = maxItems;
+ return maxItems;
+}
+
+void cNopacityDisplayMenu::Clear(void) {
+ if (detailView) {
+ delete detailView;
+ detailView = NULL;
+ }
+ menuItemIndexLast = -1;
+ initMenu = true;
+ menuItems.Clear();
+}
+
+void cNopacityDisplayMenu::SetMenuCategory(eMenuCategory MenuCategory) {
+ /* Categories:
+ mcUndefined = -1,
+ mcUnknown = 0,
+ mcMain = 1,
+ mcSchedule = 2,
+ mcChannel = 3,
+ mcTimer = 4,
+ mcRecording = 5,
+ mcPlugin = 6,
+ mcSetup = 7,
+ mcCommand = 8,
+ mcEvent = 9,
+ mcText = 10,
+ mcFolder = 11,
+ mcCam = 12
+ */
+ menuCategoryLast = this->MenuCategory();
+ cSkinDisplayMenu::SetMenuCategory(MenuCategory);
+ if ((menuCategoryLast == mcMain) && (MenuCategory != mcMain)) {
+ menuView->ShowDiskUsage(false);
+ for (cNopacityTimer *t = timers.First(); t; t = timers.Next(t)) {
+ t->SetLayer(-1);
+ }
+ diskUsageDrawn = false;
+ timersDrawn = false;
+ }
+}
+
+void cNopacityDisplayMenu::SetTitle(const char *Title) {
+ contentNarrowLast = contentNarrow;
+ menuSubCategoryLast = menuSubCategory;
+ int left = 5;
+ menuView->DestroyHeaderIcon();
+ if (Title) {
+ cString title = Title;
+ if (MenuCategory() == mcMain) {
+ title = cString::sprintf("%s %s", Title, VDRVERSION);
+ left += menuView->ShowHeaderLogo(true);
+ contentNarrow = true;
+ menuHasIcons = true;
+ } else {
+ menuView->ShowHeaderLogo(false);
+ if (MenuCategory() == mcSchedule) {
+ if (startswith(Title, trVDR("Schedule"))) {
+ menuSubCategory = mcSubSchedule;
+ left += menuView->ShowHeaderIconChannelLogo(Title);
+ menuHasIcons = true;
+ contentNarrow = true;
+ } else if (endswith(Title, "%")) {
+ //hack for epgsearch timer conflict view
+ menuSubCategory = mcSubScheduleTimer;
+ menuHasIcons = false;
+ contentNarrow = false;
+ currentNumItems = config.numDefaultMenuItems;
+ } else {
+ menuSubCategory = mcSubScheduleWhatsOn;
+ left += menuView->DrawHeaderIcon(mcSchedule);
+ menuHasIcons = true;
+ contentNarrow = true;
+ }
+ } else if (MenuCategory() == mcChannel) {
+ left += menuView->DrawHeaderIcon(mcChannel);
+ if (startswith(Title, trVDR("Channels"))) {
+ contentNarrow = true;
+ menuSubCategory = mcSubChannels;
+ menuHasIcons = true;
+ } else {
+ contentNarrow = false;
+ menuSubCategory = mcSubChannelEdit;
+ menuHasIcons = false;
+ }
+ } else {
+ left += menuView->DrawHeaderIcon(MenuCategory());
+ contentNarrow = false;
+ menuHasIcons = false;
+ }
+ }
+ menuView->AdjustContentBackground(contentNarrow, contentNarrowLast);
+ menuView->DrawHeaderLabel(left, title);
+ if (MenuCategory() == mcEvent) {
+ channelName = Title;
+ }
+ }
+}
+
+void cNopacityDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) {
+ if (Red) {
+ menuView->DrawButton(Red, handleButtons[0], Theme.Color(clrButtonRedBorder), 0);
+ } else
+ menuView->ClearButton(0);
+
+ if (Green) {
+ menuView->DrawButton(Green, handleButtons[1], Theme.Color(clrButtonGreenBorder), 1);
+ } else
+ menuView->ClearButton(1);
+
+ if (Yellow) {
+ menuView->DrawButton(Yellow, handleButtons[2], Theme.Color(clrButtonYellowBorder), 2);
+ } else
+ menuView->ClearButton(2);
+
+ if (Blue) {
+ menuView->DrawButton(Blue, handleButtons[3], Theme.Color(clrButtonBlueBorder), 3);
+ } else
+ menuView->ClearButton(3);
+}
+
+void cNopacityDisplayMenu::SetMessage(eMessageType Type, const char *Text) {
+ if (Text) {
+ menuView->DrawMessage(Type, Text);
+ } else {
+ menuView->ClearMessage();
+ }
+}
+
+void cNopacityDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable) {
+ cString *strItems = new cString[MaxTabs];
+ int *tabItems = new int[2*MaxTabs];
+ for (int i=0; i<MaxTabs; i++) {
+ strItems[i] = "";
+ tabItems[i] = 0;
+ tabItems[i+MaxTabs] = 0;
+ }
+ SplitItem(Text, strItems, tabItems);
+ int menuIconWidth = 0;
+ int menuIconHeight = 0;
+ if (initMenu) {
+ if (Index > menuItemIndexLast) {
+ cNopacityMenuItem *item;
+ cPoint itemSize;
+ if (MenuCategory() == mcMain) {
+ item = new cNopacityMainMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcMain, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcMain));
+ menuIconWidth = menuIconHeight = config.iconHeight;
+ } else if (MenuCategory() == mcSchedule) {
+ if (menuSubCategory == mcSubScheduleTimer) {
+ item = new cNopacityDefaultMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcUnknown, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcUnknown));
+ } else {
+ item = new cNopacityScheduleMenuItem(osd, Text, Current, Selectable, menuSubCategory);
+ menuView->GetMenuItemSize(mcSchedule, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcSchedule));
+ menuIconWidth = config.menuItemLogoWidth;
+ menuIconHeight = config.menuItemLogoHeight;
+ }
+ } else if (MenuCategory() == mcChannel) {
+ if (menuSubCategory == mcSubChannels) {
+ item = new cNopacityChannelMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcChannel, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcChannel));
+ menuIconWidth = config.menuItemLogoWidth;
+ menuIconHeight = config.menuItemLogoHeight;
+ } else {
+ item = new cNopacityDefaultMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcUnknown, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcUnknown));
+ }
+ } else {
+ item = new cNopacityDefaultMenuItem(osd, Text, Current, Selectable);
+ menuView->GetMenuItemSize(mcUnknown, &itemSize);
+ item->SetFont(menuView->GetMenuItemFont(mcUnknown));
+ }
+ item->SetBackgrounds(handleBackgrounds);
+ item->SetTabs(strItems, tabItems, MaxTabs);
+ int spaceTop = menuView->GetMenuTop(currentNumItems, itemSize.Y());
+ if (menuHasIcons) {
+ item->CreatePixmapIcon(spaceTop, menuView->spaceMenu, Index, itemSize.Y(), menuIconWidth, menuIconHeight);
+ }
+ item->CreatePixmap(spaceTop, menuView->spaceMenu, Index, itemSize.X(), itemSize.Y());
+ menuItems.Add(item);
+ item->Render();
+ menuItemIndexLast = Index;
+ if (initial) {
+ if (FadeTime) {
+ item->SetAlpha(0);
+ item->SetAlphaIcon(0);
+ }
+ }
+ } else {
+ //adjust Current if item was added twice
+ cNopacityMenuItem *item = menuItems.Get(Index);
+ item->SetCurrent(Current);
+ item->Render();
+ }
+ } else {
+ cNopacityMenuItem *item = menuItems.Get(Index);
+ item->SetTabs(strItems, tabItems, MaxTabs);
+ item->SetCurrent(Current);
+ item->Render();
+ }
+ SetEditableWidth(menuView->GetEditableWidth());
+}
+
+void cNopacityDisplayMenu::SplitItem(const char *Text, cString *strItems, int *tabItems) {
+ int x = 0;
+ for (int i = 0; i < MaxTabs; i++) {
+ const char *s = GetTabbedText(Text, i);
+ if (s) {
+ strItems[i] = s;
+ tabItems[i] = Tab(i);
+ if (i>0) {
+ tabItems[(i-1) + MaxTabs] = Tab(i) - x;
+ }
+ x += Tab(i) - x;
+ }
+ if (!Tab(i + 1)) {
+ tabItems[i + MaxTabs] = menuView->GetWidthDefaultMenu() - x;
+ break;
+ }
+ }
+}
+
+int cNopacityDisplayMenu::Tab(int n) {
+ return (n >= 0 && n < MaxTabs) ? menuView->mytabs[n] : 0;
+}
+
+void cNopacityDisplayMenu::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5) {
+ menuView->SetTabs(Tab1, Tab2, Tab3, Tab4, Tab5);
+}
+
+int cNopacityDisplayMenu::GetTextAreaWidth(void) const {
+ return menuView->GetTextAreaWidth();
+}
+
+const cFont *cNopacityDisplayMenu::GetTextAreaFont(bool FixedFont) const {
+ return menuView->GetTextAreaFont(FixedFont);
+}
+
+void cNopacityDisplayMenu::SetScrollbar(int Total, int Offset) {
+ if (MaxItems() >= Total) {
+ menuView->ClearScrollbar();
+ return;
+ }
+ double height = (double)MaxItems()/(double)Total;
+ double offset = (double)Offset/(double)Total;
+
+ menuView->DrawScrollbar(height, offset);
+}
+
+void cNopacityDisplayMenu::SetEvent(const cEvent *Event) {
+ if (!Event)
+ return;
+ menuView->AdjustContentBackground(false, contentNarrowLast);
+ detailView = new cNopacityMenuDetailEventView(osd, Event, channelName);
+ menuView->SetDetailViewSize(dvEvent, detailView);
+ detailView->SetFonts();
+ detailView->SetContent(Event->Description());
+ detailView->CreatePixmaps();
+ detailView->Render();
+ if (detailView->Scrollable()) {
+ double height = detailView->ScrollbarSize();
+ double offset = 0.0;
+ menuView->DrawScrollbar(height, offset);
+ }
+}
+
+void cNopacityDisplayMenu::SetRecording(const cRecording *Recording) {
+ if (!Recording)
+ return;
+ menuView->AdjustContentBackground(false, contentNarrowLast);
+ detailView = new cNopacityMenuDetailRecordingView(osd, Recording);
+ menuView->SetDetailViewSize(dvRecording, detailView);
+ detailView->SetFonts();
+ detailView->SetContent(Recording->Info()->Description());
+ detailView->CreatePixmaps();
+ detailView->Render();
+ if (detailView->Scrollable()) {
+ double height = detailView->ScrollbarSize();
+ double offset = 0.0;
+ menuView->DrawScrollbar(height, offset);
+ }
+}
+
+void cNopacityDisplayMenu::SetText(const char *Text, bool FixedFont) {
+ if (!Text)
+ return;
+ menuView->AdjustContentBackground(false, contentNarrowLast);
+ detailView = new cNopacityMenuDetailTextView(osd);
+ menuView->SetDetailViewSize(dvText, detailView);
+ detailView->SetFonts();
+ detailView->SetContent(Text);
+ detailView->CreatePixmaps();
+ detailView->Render();
+ if (detailView->Scrollable()) {
+ double height = detailView->ScrollbarSize();
+ double offset = 0.0;
+ menuView->DrawScrollbar(height, offset);
+ }
+}
+
+void cNopacityDisplayMenu::Flush(void) {
+ menuView->DrawDate(initial);
+ if (MenuCategory() == mcMain) {
+ DrawDisk();
+ DrawTimers();
+ }
+ if (initial) {
+ if (FadeTime)
+ Start();
+ }
+ initMenu = false;
+ initial = false;
+ osd->Flush();
+}
+
+void cNopacityDisplayMenu::Action(void) {
+ uint64_t Start = cTimeMs::Now();
+ while (Running()) {
+ uint64_t Now = cTimeMs::Now();
+ cPixmap::Lock();
+ double t = min(double(Now - Start) / FadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ menuView->SetPixmapAlpha(Alpha);
+ for (cNopacityMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) {
+ item->SetAlpha(Alpha);
+ item->SetAlphaIcon(Alpha);
+ }
+ for (cNopacityTimer *t = timers.First(); t; t = timers.Next(t)) {
+ t->SetAlpha(Alpha);
+ }
+ osd->Flush();
+ cPixmap::Unlock();
+ int Delta = cTimeMs::Now() - Now;
+ if (Delta < FrameTime)
+ cCondWait::SleepMs(FrameTime - Delta);
+ if ((int)(Now - Start) > FadeTime)
+ break;
+ }
+}