2014-01-10 12:44:01 +01:00
|
|
|
#include <list>
|
2013-07-09 00:17:42 +02:00
|
|
|
#include "recmenu.h"
|
|
|
|
|
|
|
|
// --- cRecMenu -------------------------------------------------------------
|
|
|
|
|
|
|
|
cRecMenu::cRecMenu(void) {
|
2013-12-21 11:25:03 +01:00
|
|
|
border = geoManager.borderRecMenus;
|
2019-06-16 14:01:22 +02:00
|
|
|
height = 2 * border;
|
2013-07-09 00:17:42 +02:00
|
|
|
headerHeight = 0;
|
|
|
|
footerHeight = 0;
|
2014-01-10 12:44:01 +01:00
|
|
|
currentHeight = 0;
|
|
|
|
deleteMenuItems = true;
|
2013-07-09 00:17:42 +02:00
|
|
|
scrollable = false;
|
|
|
|
scrollbarWidth = 3 * border;
|
|
|
|
pixmapScrollBar = NULL;
|
|
|
|
imgScrollBar = NULL;
|
|
|
|
startIndex = 0;
|
|
|
|
stopIndex = 0;
|
|
|
|
numItems = 0;
|
|
|
|
header = NULL;
|
|
|
|
footer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cRecMenu::~cRecMenu(void) {
|
|
|
|
if (header)
|
|
|
|
delete header;
|
2014-01-12 16:27:59 +01:00
|
|
|
ClearMenuItems(true);
|
2013-07-09 00:17:42 +02:00
|
|
|
if (footer)
|
|
|
|
delete footer;
|
|
|
|
if (pixmapScrollBar)
|
|
|
|
osdManager.releasePixmap(pixmapScrollBar);
|
|
|
|
if (imgScrollBar)
|
|
|
|
delete imgScrollBar;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::SetWidthPercent(int percentOSDWidth) {
|
2013-12-21 11:25:03 +01:00
|
|
|
width = geoManager.osdWidth * percentOSDWidth / 100;
|
|
|
|
x = (geoManager.osdWidth - width) / 2;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::SetWidthPixel(int pixel) {
|
|
|
|
width = pixel;
|
2013-12-21 11:25:03 +01:00
|
|
|
x = (geoManager.osdWidth - width) / 2;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int cRecMenu::CalculateOptimalWidth(void) {
|
|
|
|
int optWidth = 0;
|
2014-01-10 12:44:01 +01:00
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
int itemWidth = (*item)->GetWidth();
|
2013-07-09 00:17:42 +02:00
|
|
|
if (itemWidth > optWidth)
|
|
|
|
optWidth = itemWidth;
|
|
|
|
}
|
|
|
|
return optWidth;
|
|
|
|
}
|
|
|
|
|
2014-01-10 12:44:01 +01:00
|
|
|
bool cRecMenu::CalculateHeight(bool reDraw) {
|
2019-06-16 14:01:22 +02:00
|
|
|
int newHeight = 2 * border;
|
|
|
|
bool returnvalue = false;
|
|
|
|
if (header) {
|
2014-01-10 12:44:01 +01:00
|
|
|
newHeight += headerHeight;
|
2019-06-16 14:01:22 +02:00
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
2019-06-16 14:01:22 +02:00
|
|
|
newHeight += (*item)->GetHeight();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
2019-06-16 14:01:22 +02:00
|
|
|
if (footer) {
|
2014-01-10 12:44:01 +01:00
|
|
|
newHeight += footerHeight;
|
2019-06-16 14:01:22 +02:00
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
|
|
|
|
y = (geoManager.osdHeight - newHeight) / 2;
|
|
|
|
|
|
|
|
if (newHeight != height) {
|
|
|
|
height = newHeight;
|
2019-06-16 14:01:22 +02:00
|
|
|
returnvalue = true;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
2019-06-16 14:01:22 +02:00
|
|
|
if (scrollable && !reDraw) {
|
|
|
|
width += scrollbarWidth + border;
|
|
|
|
returnvalue = true;
|
|
|
|
}
|
|
|
|
return returnvalue;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::CreatePixmap(void) {
|
2014-01-10 12:44:01 +01:00
|
|
|
if (pixmap)
|
|
|
|
osdManager.releasePixmap(pixmap);
|
2013-07-09 00:17:42 +02:00
|
|
|
pixmap = osdManager.requestPixmap(3, cRect(x, y, width, height));
|
|
|
|
if (scrollable) {
|
|
|
|
int scrollBarX = x + width - scrollbarWidth - border;
|
|
|
|
int scrollBarY = y + border + headerHeight;
|
|
|
|
int scrollBarHeight = height - headerHeight - footerHeight - 2 * border;
|
2014-01-10 12:44:01 +01:00
|
|
|
if (pixmapScrollBar)
|
|
|
|
osdManager.releasePixmap(pixmapScrollBar);
|
2013-07-09 00:17:42 +02:00
|
|
|
pixmapScrollBar = osdManager.requestPixmap(4, cRect(scrollBarX, scrollBarY, scrollbarWidth, scrollBarHeight));
|
2014-01-10 12:44:01 +01:00
|
|
|
} else
|
|
|
|
pixmapScrollBar = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::SetHeader(cRecMenuItem *header) {
|
|
|
|
this->header = header;
|
|
|
|
headerHeight = header->GetHeight();
|
|
|
|
height += headerHeight;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::SetFooter(cRecMenuItem *footer) {
|
|
|
|
this->footer = footer;
|
|
|
|
footerHeight = footer->GetHeight();
|
|
|
|
height += footerHeight;
|
|
|
|
}
|
|
|
|
|
2014-01-12 16:27:59 +01:00
|
|
|
void cRecMenu::ClearMenuItems(bool destructor) {
|
|
|
|
for (std::list<cRecMenuItem*>::iterator it = menuItems.begin(); it != menuItems.end(); it++) {
|
|
|
|
if (deleteMenuItems)
|
2014-01-10 12:44:01 +01:00
|
|
|
delete *it;
|
2014-01-12 16:27:59 +01:00
|
|
|
else if (!destructor)
|
|
|
|
(*it)->Hide();
|
2014-01-10 12:44:01 +01:00
|
|
|
}
|
|
|
|
menuItems.clear();
|
|
|
|
};
|
2013-07-09 00:17:42 +02:00
|
|
|
|
2014-01-10 12:44:01 +01:00
|
|
|
void cRecMenu::InitMenu(bool complete) {
|
|
|
|
currentHeight = 0;
|
|
|
|
numItems = 0;
|
|
|
|
if (scrollable) {
|
|
|
|
width -= scrollbarWidth + border;
|
|
|
|
osdManager.releasePixmap(pixmapScrollBar);
|
|
|
|
pixmapScrollBar = NULL;
|
|
|
|
delete imgScrollBar;
|
|
|
|
imgScrollBar = NULL;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
osdManager.releasePixmap(pixmap);
|
|
|
|
pixmap = NULL;
|
|
|
|
for (std::list<cRecMenuItem*>::iterator it = menuItems.begin(); it != menuItems.end(); it++) {
|
|
|
|
if (deleteMenuItems)
|
|
|
|
delete *it;
|
|
|
|
else
|
|
|
|
(*it)->Hide();
|
|
|
|
}
|
|
|
|
menuItems.clear();
|
|
|
|
if (complete) {
|
|
|
|
startIndex = 0;
|
|
|
|
stopIndex = 0;
|
|
|
|
scrollable = false;
|
|
|
|
} else {
|
|
|
|
stopIndex = startIndex;
|
|
|
|
}
|
|
|
|
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
2014-01-10 12:44:01 +01:00
|
|
|
void cRecMenu::AddMenuItem(cRecMenuItem *item, bool inFront) {
|
2014-01-12 16:27:59 +01:00
|
|
|
item->Show();
|
2014-01-10 12:44:01 +01:00
|
|
|
if (!inFront)
|
|
|
|
menuItems.push_back(item);
|
|
|
|
else
|
|
|
|
menuItems.push_front(item);
|
|
|
|
}
|
|
|
|
|
2014-01-18 14:10:42 +01:00
|
|
|
bool cRecMenu::AddMenuItemInitial(cRecMenuItem *item, bool inFront) {
|
2014-01-10 12:44:01 +01:00
|
|
|
currentHeight += item->GetHeight();
|
|
|
|
int totalHeight = headerHeight + footerHeight + currentHeight + 2*border;
|
2019-06-16 14:01:22 +02:00
|
|
|
if (totalHeight >= geoManager.osdHeight - 80) {
|
2014-01-10 12:44:01 +01:00
|
|
|
scrollable = true;
|
|
|
|
currentHeight -= item->GetHeight();
|
|
|
|
if (deleteMenuItems) {
|
|
|
|
delete item;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
return false;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
numItems++;
|
2014-01-18 14:10:42 +01:00
|
|
|
if (!inFront) {
|
|
|
|
stopIndex++;
|
|
|
|
menuItems.push_back(item);
|
|
|
|
} else {
|
|
|
|
startIndex--;
|
|
|
|
menuItems.push_front(item);
|
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::Activate(cRecMenuItem *itemOld, cRecMenuItem *item) {
|
|
|
|
itemOld->setInactive();
|
|
|
|
itemOld->setBackground();
|
|
|
|
itemOld->Draw();
|
|
|
|
item->setActive();
|
|
|
|
item->setBackground();
|
|
|
|
item->Draw();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool cRecMenu::ActivatePrev(void) {
|
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
if (!scrollable && footer && footer->isActive()) {
|
2014-01-10 12:44:01 +01:00
|
|
|
if (menuItems.size() > 0) {
|
|
|
|
cRecMenuItem *itemLast = menuItems.back();
|
|
|
|
Activate(footer, itemLast);
|
|
|
|
return true;
|
|
|
|
}
|
2013-07-09 00:17:42 +02:00
|
|
|
} else if (activeItem) {
|
|
|
|
cRecMenuItem *prev = NULL;
|
2014-01-10 12:44:01 +01:00
|
|
|
bool foundActive = false;
|
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.end(); item != menuItems.begin(); ) {
|
|
|
|
item--;
|
|
|
|
if (*item == activeItem) {
|
|
|
|
foundActive = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!foundActive)
|
|
|
|
continue;
|
|
|
|
if ((*item)->isSelectable()) {
|
|
|
|
prev = *item;
|
2013-07-09 00:17:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (prev) {
|
|
|
|
Activate(activeItem , prev);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-12 16:27:59 +01:00
|
|
|
bool cRecMenu::ScrollUp(void) {
|
2013-07-09 00:17:42 +02:00
|
|
|
if (footer && footer->isActive()) {
|
2014-01-10 12:44:01 +01:00
|
|
|
if (menuItems.size() > 0)
|
|
|
|
Activate(footer, menuItems.back());
|
2013-07-09 00:17:42 +02:00
|
|
|
} else {
|
|
|
|
//get perv x items
|
|
|
|
int numNewItems = numItems / 2;
|
|
|
|
int numAdded = 0;
|
|
|
|
cRecMenuItem *newItem = NULL;
|
|
|
|
while (newItem = GetMenuItem(startIndex-1)) {
|
2014-01-10 12:44:01 +01:00
|
|
|
AddMenuItem(newItem, true);
|
|
|
|
cRecMenuItem *last = menuItems.back();
|
|
|
|
if (deleteMenuItems) {
|
|
|
|
delete last;
|
|
|
|
} else {
|
|
|
|
last->setInactive();
|
|
|
|
last->Hide();
|
|
|
|
}
|
|
|
|
menuItems.pop_back();
|
2013-07-09 00:17:42 +02:00
|
|
|
stopIndex--;
|
|
|
|
startIndex--;
|
|
|
|
numAdded++;
|
|
|
|
if (numAdded >= numNewItems)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (numAdded != 0) {
|
2014-01-10 12:44:01 +01:00
|
|
|
scrollable = true;
|
|
|
|
if (CalculateHeight(true))
|
|
|
|
CreatePixmap();
|
|
|
|
Arrange(deleteMenuItems);
|
|
|
|
Display(deleteMenuItems);
|
2013-07-09 00:17:42 +02:00
|
|
|
ActivatePrev();
|
2014-01-12 16:27:59 +01:00
|
|
|
} else {
|
|
|
|
return false;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
}
|
2014-01-12 16:27:59 +01:00
|
|
|
return true;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
2014-01-10 12:44:01 +01:00
|
|
|
bool cRecMenu::ActivateNext(void) {
|
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
if (activeItem) {
|
|
|
|
cRecMenuItem *next = NULL;
|
|
|
|
bool foundActive = false;
|
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
if (*item == activeItem) {
|
|
|
|
foundActive = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!foundActive)
|
|
|
|
continue;
|
|
|
|
if ((*item)->isSelectable()) {
|
|
|
|
next = *item;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (next) {
|
|
|
|
Activate(activeItem , next);
|
|
|
|
return true;
|
2014-01-12 16:27:59 +01:00
|
|
|
} else if (!scrollable && footer && footer->isSelectable() && !footer->isActive()) {
|
2014-01-10 12:44:01 +01:00
|
|
|
Activate(activeItem , footer);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-12 16:27:59 +01:00
|
|
|
bool cRecMenu::ScrollDown(void) {
|
2013-07-09 00:17:42 +02:00
|
|
|
//get next x items
|
|
|
|
int numNewItems = numItems / 2;
|
|
|
|
int numAdded = 0;
|
|
|
|
cRecMenuItem *newItem = NULL;
|
|
|
|
while (newItem = GetMenuItem(stopIndex)) {
|
2014-01-10 12:44:01 +01:00
|
|
|
menuItems.push_back(newItem);
|
|
|
|
cRecMenuItem *first = menuItems.front();
|
|
|
|
if (deleteMenuItems) {
|
|
|
|
delete first;
|
|
|
|
} else {
|
|
|
|
first->setInactive();
|
|
|
|
first->Hide();
|
|
|
|
}
|
|
|
|
menuItems.pop_front();
|
2013-07-09 00:17:42 +02:00
|
|
|
startIndex++;
|
2014-01-10 12:44:01 +01:00
|
|
|
stopIndex++;
|
2013-07-09 00:17:42 +02:00
|
|
|
numAdded++;
|
|
|
|
if (numAdded >= numNewItems)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (numAdded != 0) {
|
2014-01-10 12:44:01 +01:00
|
|
|
scrollable = true;
|
|
|
|
if (CalculateHeight(true))
|
|
|
|
CreatePixmap();
|
|
|
|
Arrange(deleteMenuItems);
|
|
|
|
Display(deleteMenuItems);
|
2013-07-09 00:17:42 +02:00
|
|
|
ActivateNext();
|
|
|
|
} else {
|
2014-01-12 16:27:59 +01:00
|
|
|
//last item reached, activate footer if not already active
|
|
|
|
if ((footer) && !(footer->isActive())) {
|
2013-07-09 00:17:42 +02:00
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
Activate(activeItem , footer);
|
2014-01-12 16:27:59 +01:00
|
|
|
} else {
|
|
|
|
return false;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
}
|
2014-01-12 16:27:59 +01:00
|
|
|
return true;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
2014-01-18 14:10:42 +01:00
|
|
|
void cRecMenu::PageUp(void) {
|
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
if (!activeItem)
|
|
|
|
return;
|
|
|
|
if (!scrollable) {
|
|
|
|
JumpBegin();
|
|
|
|
return;
|
|
|
|
}
|
2014-02-06 17:53:20 +01:00
|
|
|
if (footer && activeItem == footer) {
|
|
|
|
Activate(footer, menuItems.front());
|
|
|
|
return;
|
|
|
|
}
|
2014-01-18 14:10:42 +01:00
|
|
|
int newActive = GetActive() - numItems;
|
|
|
|
if (newActive < 0)
|
|
|
|
newActive = 0;
|
|
|
|
activeItem->setInactive();
|
|
|
|
activeItem->setBackground();
|
|
|
|
ClearMenuItems();
|
|
|
|
currentHeight = 0;
|
|
|
|
stopIndex = startIndex;
|
|
|
|
numItems = 0;
|
|
|
|
cRecMenuItem *newItem = NULL;
|
|
|
|
bool spaceLeft = true;
|
|
|
|
while (newItem = GetMenuItem(startIndex-1)) {
|
|
|
|
if (startIndex-1 == newActive)
|
|
|
|
newItem->setActive();
|
|
|
|
spaceLeft = AddMenuItemInitial(newItem, true);
|
|
|
|
if (!spaceLeft)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (spaceLeft) {
|
|
|
|
while (newItem = GetMenuItem(stopIndex)) {
|
|
|
|
spaceLeft = AddMenuItemInitial(newItem);
|
|
|
|
if (!spaceLeft)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (GetActive() == numItems)
|
|
|
|
menuItems.front()->setActive();
|
|
|
|
if (CalculateHeight(true))
|
|
|
|
CreatePixmap();
|
|
|
|
Arrange(deleteMenuItems);
|
|
|
|
Display(deleteMenuItems);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::PageDown(void) {
|
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
if (!activeItem)
|
|
|
|
return;
|
2014-02-06 17:53:20 +01:00
|
|
|
if (footer && activeItem == footer) {
|
|
|
|
return;
|
|
|
|
}
|
2014-01-18 14:10:42 +01:00
|
|
|
if (!scrollable) {
|
|
|
|
JumpEnd();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int newActive = GetActive() + numItems;
|
|
|
|
activeItem->setInactive();
|
|
|
|
activeItem->setBackground();
|
|
|
|
ClearMenuItems();
|
|
|
|
currentHeight = 0;
|
|
|
|
numItems = 0;
|
|
|
|
startIndex = stopIndex;
|
|
|
|
cRecMenuItem *newItem = NULL;
|
|
|
|
bool spaceLeft = true;
|
|
|
|
while (newItem = GetMenuItem(stopIndex)) {
|
|
|
|
if (stopIndex == newActive)
|
|
|
|
newItem->setActive();
|
|
|
|
spaceLeft = AddMenuItemInitial(newItem);
|
|
|
|
if (!spaceLeft)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (spaceLeft) {
|
|
|
|
while (newItem = GetMenuItem(startIndex-1)) {
|
|
|
|
spaceLeft = AddMenuItemInitial(newItem, true);
|
|
|
|
if (!spaceLeft)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (GetActive() == GetTotalNumMenuItems())
|
|
|
|
menuItems.back()->setActive();
|
|
|
|
if (CalculateHeight(true))
|
|
|
|
CreatePixmap();
|
|
|
|
Arrange(deleteMenuItems);
|
|
|
|
Display(deleteMenuItems);
|
|
|
|
}
|
|
|
|
|
2013-07-09 00:17:42 +02:00
|
|
|
void cRecMenu::JumpBegin(void) {
|
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
if (!scrollable) {
|
|
|
|
cRecMenuItem *firstSelectable= NULL;
|
2014-01-10 12:44:01 +01:00
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
if ((*item)->isSelectable()) {
|
|
|
|
firstSelectable = *item;
|
2013-07-09 00:17:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (activeItem && firstSelectable) {
|
|
|
|
Activate(activeItem , firstSelectable);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
activeItem->setInactive();
|
|
|
|
activeItem->setBackground();
|
|
|
|
if (footer)
|
|
|
|
footer->Draw();
|
2014-01-10 12:44:01 +01:00
|
|
|
ClearMenuItems();
|
2013-07-09 00:17:42 +02:00
|
|
|
int currentItem = 0;
|
|
|
|
cRecMenuItem *newItem = NULL;
|
|
|
|
while (newItem = GetMenuItem(currentItem)) {
|
|
|
|
AddMenuItem(newItem);
|
|
|
|
currentItem++;
|
|
|
|
if (currentItem >= numItems)
|
|
|
|
break;
|
|
|
|
}
|
2019-06-16 14:01:22 +02:00
|
|
|
if (CalculateHeight(true))
|
|
|
|
CreatePixmap();
|
|
|
|
Arrange(false);
|
2013-07-09 00:17:42 +02:00
|
|
|
startIndex = 0;
|
2019-06-16 14:01:22 +02:00
|
|
|
stopIndex = numItems - 1;
|
2014-01-10 12:44:01 +01:00
|
|
|
cRecMenuItem *first = menuItems.front();
|
|
|
|
first->setActive();
|
|
|
|
first->setBackground();
|
|
|
|
first->Draw();
|
2019-06-16 14:01:22 +02:00
|
|
|
Display(false);
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::JumpEnd(void) {
|
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
if (!activeItem)
|
|
|
|
return;
|
|
|
|
if (!scrollable) {
|
|
|
|
cRecMenuItem *lastSelectable= NULL;
|
|
|
|
if (footer && footer->isSelectable()) {
|
|
|
|
lastSelectable = footer;
|
|
|
|
} else {
|
2014-01-10 12:44:01 +01:00
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.end(); item != menuItems.begin(); ) {
|
|
|
|
item--;
|
|
|
|
if ((*item)->isSelectable()) {
|
|
|
|
lastSelectable = *item;
|
2013-07-09 00:17:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (lastSelectable) {
|
|
|
|
Activate(activeItem , lastSelectable);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
activeItem->setInactive();
|
|
|
|
activeItem->setBackground();
|
2014-01-10 12:44:01 +01:00
|
|
|
ClearMenuItems();
|
2013-07-09 00:17:42 +02:00
|
|
|
int totalNumItems = GetTotalNumMenuItems();
|
2019-06-16 14:01:22 +02:00
|
|
|
int currentItem = totalNumItems - 1;
|
2013-07-09 00:17:42 +02:00
|
|
|
int itemsAdded = 0;
|
|
|
|
cRecMenuItem *newItem = NULL;
|
|
|
|
while (newItem = GetMenuItem(currentItem)) {
|
2014-01-10 12:44:01 +01:00
|
|
|
AddMenuItem(newItem, true);
|
2013-07-09 00:17:42 +02:00
|
|
|
currentItem--;
|
|
|
|
itemsAdded++;
|
|
|
|
if (itemsAdded >= numItems)
|
|
|
|
break;
|
|
|
|
}
|
2019-06-16 14:01:22 +02:00
|
|
|
if (CalculateHeight(true))
|
|
|
|
CreatePixmap();
|
|
|
|
Arrange(false);
|
2013-07-09 00:17:42 +02:00
|
|
|
stopIndex = totalNumItems;
|
|
|
|
startIndex = stopIndex - numItems;
|
|
|
|
if (footer) {
|
|
|
|
footer->setActive();
|
|
|
|
footer->setBackground();
|
|
|
|
footer->Draw();
|
|
|
|
} else {
|
2014-01-10 12:44:01 +01:00
|
|
|
cRecMenuItem *last = menuItems.back();
|
|
|
|
last->setActive();
|
|
|
|
last->setBackground();
|
|
|
|
last->Draw();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
2019-06-16 14:01:22 +02:00
|
|
|
Display(false);
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::Arrange(bool scroll) {
|
|
|
|
int xElement = x + border;
|
|
|
|
int yElement = y + border;
|
|
|
|
int widthElement = width - 2 * border;
|
|
|
|
if (scrollable)
|
|
|
|
widthElement -= scrollbarWidth + border;
|
|
|
|
|
|
|
|
if (header) {
|
|
|
|
if (!scroll) {
|
|
|
|
header->SetGeometry(xElement, yElement, widthElement);
|
|
|
|
header->SetPixmaps();
|
2013-12-29 18:13:45 +01:00
|
|
|
header->setBackground();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
yElement += header->GetHeight();
|
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
(*item)->SetGeometry(xElement, yElement, widthElement);
|
|
|
|
(*item)->SetPixmaps();
|
|
|
|
yElement += (*item)->GetHeight();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
if (footer && !scroll) {
|
|
|
|
footer->SetGeometry(xElement, yElement, widthElement);
|
|
|
|
footer->SetPixmaps();
|
2013-12-29 18:13:45 +01:00
|
|
|
footer->setBackground();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::Display(bool scroll) {
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.style == eStyleGraphical) {
|
2013-12-21 11:25:03 +01:00
|
|
|
drawBackgroundGraphical(bgRecMenuBack);
|
|
|
|
} else {
|
|
|
|
pixmap->Fill(theme.Color(clrBackground));
|
|
|
|
drawBorder();
|
|
|
|
}
|
2013-07-09 00:17:42 +02:00
|
|
|
if (header && !scroll) {
|
|
|
|
header->setBackground();
|
|
|
|
header->Draw();
|
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
(*item)->setBackground();
|
|
|
|
(*item)->Show();
|
|
|
|
(*item)->Draw();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
if (footer && !scroll) {
|
|
|
|
footer->setBackground();
|
|
|
|
footer->Draw();
|
|
|
|
}
|
|
|
|
if (scrollable)
|
|
|
|
DrawScrollBar();
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::Hide(void) {
|
|
|
|
pixmap->SetLayer(-1);
|
|
|
|
if (pixmapScrollBar)
|
|
|
|
pixmapScrollBar->SetLayer(-1);
|
|
|
|
if (header)
|
|
|
|
header->Hide();
|
|
|
|
if (footer)
|
|
|
|
footer->Hide();
|
2014-01-10 12:44:01 +01:00
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
(*item)->Hide();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cRecMenu::Show(void) {
|
|
|
|
pixmap->SetLayer(3);
|
|
|
|
if (pixmapScrollBar)
|
|
|
|
pixmapScrollBar->SetLayer(3);
|
|
|
|
if (header)
|
|
|
|
header->Show();
|
|
|
|
if (footer)
|
|
|
|
footer->Show();
|
2014-01-10 12:44:01 +01:00
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
(*item)->Show();
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-07 17:57:14 +01:00
|
|
|
void cRecMenu::UpdateActiveMenuItem(void) {
|
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
if (activeItem)
|
|
|
|
activeItem->Draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-09 00:17:42 +02:00
|
|
|
void cRecMenu::DrawScrollBar(void) {
|
|
|
|
pixmapScrollBar->Fill(theme.Color(clrBorder));
|
|
|
|
pixmapScrollBar->DrawRectangle(cRect(2,2,pixmapScrollBar->ViewPort().Width()-4, pixmapScrollBar->ViewPort().Height() - 4), theme.Color(clrBackground));
|
|
|
|
|
|
|
|
int totalNumItems = GetTotalNumMenuItems();
|
|
|
|
if (imgScrollBar == NULL) {
|
|
|
|
int scrollBarImgHeight = (pixmapScrollBar->ViewPort().Height() - 8) * numItems / totalNumItems;
|
|
|
|
imgScrollBar = createScrollbar(pixmapScrollBar->ViewPort().Width()-8, scrollBarImgHeight, theme.Color(clrHighlight), theme.Color(clrHighlightBlending));
|
|
|
|
}
|
|
|
|
int offset = (pixmapScrollBar->ViewPort().Height() - 8) * startIndex / totalNumItems;
|
|
|
|
pixmapScrollBar->DrawImage(cPoint(4, 2 + offset), *imgScrollBar);
|
|
|
|
}
|
|
|
|
|
2014-01-10 12:44:01 +01:00
|
|
|
cRecMenuItem *cRecMenu::GetActiveMenuItem(void) {
|
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
if ((*item)->isActive())
|
|
|
|
return *item;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
if (footer && footer->isActive())
|
|
|
|
return footer;
|
|
|
|
return NULL;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
|
2014-01-10 12:44:01 +01:00
|
|
|
cRecMenuItem *cRecMenu::GetMenuItemAt(int num) {
|
|
|
|
int current = 0;
|
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
if (current == num)
|
|
|
|
return *item;
|
|
|
|
current++;
|
2013-07-09 00:17:42 +02:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-01-10 12:44:01 +01:00
|
|
|
int cRecMenu::GetActive(void) {
|
|
|
|
int numActive = startIndex;
|
|
|
|
for (std::list<cRecMenuItem*>::iterator item = menuItems.begin(); item != menuItems.end(); item++) {
|
|
|
|
if ((*item)->isActive()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
numActive++;
|
2014-01-03 11:56:45 +01:00
|
|
|
}
|
2014-01-10 12:44:01 +01:00
|
|
|
return numActive;
|
2014-01-03 11:56:45 +01:00
|
|
|
}
|
|
|
|
|
2013-07-09 00:17:42 +02:00
|
|
|
eRecMenuState cRecMenu::ProcessKey(eKeys Key) {
|
|
|
|
cRecMenuItem *activeItem = GetActiveMenuItem();
|
|
|
|
eRecMenuState state = rmsContinue;
|
|
|
|
if (!activeItem)
|
|
|
|
return state;
|
|
|
|
|
|
|
|
state = activeItem->ProcessKey(Key);
|
|
|
|
if (state == rmsRefresh) {
|
|
|
|
CreateMenuItems();
|
|
|
|
Display();
|
|
|
|
} else if (state == rmsNotConsumed) {
|
|
|
|
switch (Key & ~k_Repeat) {
|
|
|
|
case kUp:
|
2014-01-10 12:44:01 +01:00
|
|
|
if (!ActivatePrev())
|
2014-01-12 16:27:59 +01:00
|
|
|
if (!ScrollUp())
|
|
|
|
JumpEnd();
|
|
|
|
state = rmsConsumed;
|
2013-07-09 00:17:42 +02:00
|
|
|
break;
|
2014-01-12 16:27:59 +01:00
|
|
|
case kDown:
|
2014-01-10 12:44:01 +01:00
|
|
|
if (!ActivateNext())
|
2014-01-12 16:27:59 +01:00
|
|
|
if (!ScrollDown())
|
|
|
|
JumpBegin();
|
|
|
|
state = rmsConsumed;
|
2013-07-09 00:17:42 +02:00
|
|
|
break;
|
|
|
|
case kLeft:
|
2014-01-18 14:10:42 +01:00
|
|
|
PageUp();
|
2013-07-09 00:17:42 +02:00
|
|
|
state = rmsConsumed;
|
|
|
|
break;
|
|
|
|
case kRight:
|
2014-01-18 14:10:42 +01:00
|
|
|
PageDown();
|
2013-07-09 00:17:42 +02:00
|
|
|
state = rmsConsumed;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
cImage *cRecMenu::createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend) {
|
|
|
|
cImage *image = new cImage(cSize(width, height));
|
|
|
|
image->Fill(clrBgr);
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.style != eStyleFlat) {
|
2013-07-09 00:17:42 +02:00
|
|
|
int numSteps = 64;
|
|
|
|
int alphaStep = 0x03;
|
|
|
|
if (height < 30)
|
|
|
|
return image;
|
|
|
|
else if (height < 100) {
|
|
|
|
numSteps = 32;
|
|
|
|
alphaStep = 0x06;
|
|
|
|
}
|
|
|
|
int stepY = 0.5*height / numSteps;
|
|
|
|
if (stepY == 0)
|
|
|
|
stepY = 1;
|
|
|
|
int alpha = 0x40;
|
|
|
|
tColor clr;
|
|
|
|
for (int i = 0; i<numSteps; i++) {
|
|
|
|
clr = AlphaBlend(clrBgr, clrBlend, alpha);
|
|
|
|
for (int y = i*stepY; y < (i+1)*stepY; y++) {
|
|
|
|
for (int x=0; x<width; x++) {
|
|
|
|
image->SetPixel(cPoint(x,y), clr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
alpha += alphaStep;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return image;
|
2019-06-16 14:01:22 +02:00
|
|
|
}
|