1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-07-04 20:40:44 +03:00

Changed section headers to be displayed in a circular fashion

Instead of having a list and wrapping between beginning and end, always
put the current section in the middle and show the previous and next
sections using wrap-around.
This commit is contained in:
Maarten ter Huurne 2013-08-05 14:54:42 +02:00
parent 903ccc2cfe
commit e6300ab07a
2 changed files with 49 additions and 49 deletions

View File

@ -45,8 +45,6 @@ Menu::Menu(GMenu2X *gmenu2x, Touchscreen &ts)
: gmenu2x(gmenu2x) : gmenu2x(gmenu2x)
, ts(ts) , ts(ts)
{ {
iFirstDispSection = 0;
readSections(GMENU2X_SYSTEM_DIR "/sections"); readSections(GMENU2X_SYSTEM_DIR "/sections");
readSections(GMenu2X::getHome() + "/sections"); readSections(GMenu2X::getHome() + "/sections");
@ -131,6 +129,19 @@ void Menu::skinUpdated() {
} }
} }
void Menu::calcSectionRange(int &leftSection, int &rightSection) {
ConfIntHash &skinConfInt = gmenu2x->skinConfInt;
const int linkWidth = skinConfInt["linkWidth"];
const int screenWidth = gmenu2x->resX;
const int numSections = sections.size();
rightSection = min(
max(1, (screenWidth - 20 - linkWidth) / (2 * linkWidth)),
numSections / 2);
leftSection = max(
-rightSection,
rightSection - numSections + 1);
}
void Menu::paint(Surface &s) { void Menu::paint(Surface &s) {
const uint width = s.width(), height = s.height(); const uint width = s.width(), height = s.height();
Font &font = *gmenu2x->font; Font &font = *gmenu2x->font;
@ -143,34 +154,25 @@ void Menu::paint(Surface &s) {
const int linkHeight = skinConfInt["linkHeight"]; const int linkHeight = skinConfInt["linkHeight"];
RGBAColor &selectionBgColor = gmenu2x->skinConfColors[COLOR_SELECTION_BG]; RGBAColor &selectionBgColor = gmenu2x->skinConfColors[COLOR_SELECTION_BG];
//Sections // Paint section headers.
int leftSection, rightSection;
calcSectionRange(leftSection, rightSection);
s.box(width / 2 - linkWidth / 2, 0, linkWidth, topBarHeight, selectionBgColor);
const uint sectionLinkPadding = (topBarHeight - 32 - font.getHeight()) / 3; const uint sectionLinkPadding = (topBarHeight - 32 - font.getHeight()) / 3;
const uint sectionsCoordX = const uint numSections = sections.size();
(width - constrain((uint)sections.size(), 0 , linkColumns) * linkWidth) / 2; for (int i = leftSection; i <= rightSection; i++) {
if (iFirstDispSection > 0) { uint j = (iSection + numSections + i) % numSections;
sc.skinRes("imgs/l_enabled.png")->blit(&s, 0, 0); string sectionIcon = "skin:sections/" + sections[j] + ".png";
} else { Surface *icon = sc.exists(sectionIcon)
sc.skinRes("imgs/l_disabled.png")->blit(&s, 0, 0); ? sc[sectionIcon]
} : sc.skinRes("icons/section.png");
if (iFirstDispSection + linkColumns < sections.size()) { const int x = width / 2 + i * linkWidth;
sc.skinRes("imgs/r_enabled.png")->blit(&s, width - 10, 0); icon->blit(&s, x - 16, sectionLinkPadding, 32, 32);
} else { s.write(&font, sections[j], x, topBarHeight - sectionLinkPadding,
sc.skinRes("imgs/r_disabled.png")->blit(&s, width - 10, 0); Font::HAlignCenter, Font::VAlignBottom);
}
for (uint i = iFirstDispSection; i < sections.size() && i < iFirstDispSection + linkColumns; i++) {
string sectionIcon = "skin:sections/" + sections[i] + ".png";
int x = (i - iFirstDispSection) * linkWidth + sectionsCoordX;
if (i == (uint)iSection) {
s.box(x, 0, linkWidth, topBarHeight, selectionBgColor);
}
x += linkWidth / 2;
if (sc.exists(sectionIcon)) {
sc[sectionIcon]->blit(&s, x - 16, sectionLinkPadding, 32, 32);
} else {
sc.skinRes("icons/section.png")->blit(&s, x - 16, sectionLinkPadding);
}
s.write(&font, sections[i], x, topBarHeight - sectionLinkPadding, Font::HAlignCenter, Font::VAlignBottom);
} }
sc.skinRes("imgs/l_enabled.png")->blit(&s, 0, 0);
sc.skinRes("imgs/r_enabled.png")->blit(&s, width - 10, 0);
vector<Link*> &sectionLinks = links[iSection]; vector<Link*> &sectionLinks = links[iSection];
const uint numLinks = sectionLinks.size(); const uint numLinks = sectionLinks.size();
@ -208,24 +210,21 @@ void Menu::paint(Surface &s) {
void Menu::handleTS() { void Menu::handleTS() {
ConfIntHash &skinConfInt = gmenu2x->skinConfInt; ConfIntHash &skinConfInt = gmenu2x->skinConfInt;
const int topBarHeight = skinConfInt["topBarHeight"]; const int topBarHeight = skinConfInt["topBarHeight"];
const int linkWidth = skinConfInt["linkWidth"];
const int screenWidth = gmenu2x->resX; const int screenWidth = gmenu2x->resX;
SDL_Rect re = { if (ts.pressed() && ts.getY() < topBarHeight) {
0, 0, int leftSection, rightSection;
static_cast<Uint16>(screenWidth), static_cast<Uint16>(topBarHeight) calcSectionRange(leftSection, rightSection);
};
if (ts.pressed() && ts.inRect(re)) {
re.w = linkWidth;
uint sectionsCoordX = (screenWidth - constrain((uint)sections.size(), 0, linkColumns) * linkWidth) / 2;
for (uint i = iFirstDispSection; !ts.handled() && i < sections.size() && i < iFirstDispSection + linkColumns; i++) {
re.x = (i - iFirstDispSection) * re.w + sectionsCoordX;
if (ts.inRect(re)) { const int linkWidth = skinConfInt["linkWidth"];
setSectionIndex(i); const int leftSectionX = screenWidth / 2 + leftSection * linkWidth;
ts.setHandled(); const int i = min(
} leftSection + max((ts.getX() - leftSectionX) / linkWidth, 0),
} rightSection);
const uint numSections = sections.size();
setSectionIndex((iSection + numSections + i) % numSections);
ts.setHandled();
} }
const uint linksPerPage = linkColumns * linkRows; const uint linksPerPage = linkColumns * linkRows;
@ -283,11 +282,6 @@ void Menu::setSectionIndex(int i) {
i=0; i=0;
iSection = i; iSection = i;
if (i>(int)iFirstDispSection+2)
iFirstDispSection = i-2;
else if (i<(int)iFirstDispSection)
iFirstDispSection = i;
iLink = 0; iLink = 0;
iFirstDispRow = 0; iFirstDispRow = 0;
} }

View File

@ -42,12 +42,18 @@ private:
GMenu2X *gmenu2x; GMenu2X *gmenu2x;
Touchscreen &ts; Touchscreen &ts;
int iSection, iLink; int iSection, iLink;
uint iFirstDispSection, iFirstDispRow; uint iFirstDispRow;
std::vector<std::string> sections; std::vector<std::string> sections;
std::vector< std::vector<Link*> > links; std::vector< std::vector<Link*> > links;
uint linkColumns, linkRows; uint linkColumns, linkRows;
/**
* Determine which section headers are visible.
* The output values are relative to the middle section at 0.
*/
void calcSectionRange(int &leftSection, int &rightSection);
std::vector<Link*> *sectionLinks(int i = -1); std::vector<Link*> *sectionLinks(int i = -1);
void readLinks(); void readLinks();