mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-12-28 00:56:47 +02: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:
parent
903ccc2cfe
commit
e6300ab07a
90
src/menu.cpp
90
src/menu.cpp
@ -45,8 +45,6 @@ Menu::Menu(GMenu2X *gmenu2x, Touchscreen &ts)
|
||||
: gmenu2x(gmenu2x)
|
||||
, ts(ts)
|
||||
{
|
||||
iFirstDispSection = 0;
|
||||
|
||||
readSections(GMENU2X_SYSTEM_DIR "/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) {
|
||||
const uint width = s.width(), height = s.height();
|
||||
Font &font = *gmenu2x->font;
|
||||
@ -143,34 +154,25 @@ void Menu::paint(Surface &s) {
|
||||
const int linkHeight = skinConfInt["linkHeight"];
|
||||
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 sectionsCoordX =
|
||||
(width - constrain((uint)sections.size(), 0 , linkColumns) * linkWidth) / 2;
|
||||
if (iFirstDispSection > 0) {
|
||||
sc.skinRes("imgs/l_enabled.png")->blit(&s, 0, 0);
|
||||
} else {
|
||||
sc.skinRes("imgs/l_disabled.png")->blit(&s, 0, 0);
|
||||
}
|
||||
if (iFirstDispSection + linkColumns < sections.size()) {
|
||||
sc.skinRes("imgs/r_enabled.png")->blit(&s, width - 10, 0);
|
||||
} else {
|
||||
sc.skinRes("imgs/r_disabled.png")->blit(&s, width - 10, 0);
|
||||
}
|
||||
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);
|
||||
const uint numSections = sections.size();
|
||||
for (int i = leftSection; i <= rightSection; i++) {
|
||||
uint j = (iSection + numSections + i) % numSections;
|
||||
string sectionIcon = "skin:sections/" + sections[j] + ".png";
|
||||
Surface *icon = sc.exists(sectionIcon)
|
||||
? sc[sectionIcon]
|
||||
: sc.skinRes("icons/section.png");
|
||||
const int x = width / 2 + i * linkWidth;
|
||||
icon->blit(&s, x - 16, sectionLinkPadding, 32, 32);
|
||||
s.write(&font, sections[j], 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*> §ionLinks = links[iSection];
|
||||
const uint numLinks = sectionLinks.size();
|
||||
@ -208,24 +210,21 @@ void Menu::paint(Surface &s) {
|
||||
void Menu::handleTS() {
|
||||
ConfIntHash &skinConfInt = gmenu2x->skinConfInt;
|
||||
const int topBarHeight = skinConfInt["topBarHeight"];
|
||||
const int linkWidth = skinConfInt["linkWidth"];
|
||||
const int screenWidth = gmenu2x->resX;
|
||||
|
||||
SDL_Rect re = {
|
||||
0, 0,
|
||||
static_cast<Uint16>(screenWidth), static_cast<Uint16>(topBarHeight)
|
||||
};
|
||||
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.pressed() && ts.getY() < topBarHeight) {
|
||||
int leftSection, rightSection;
|
||||
calcSectionRange(leftSection, rightSection);
|
||||
|
||||
if (ts.inRect(re)) {
|
||||
setSectionIndex(i);
|
||||
ts.setHandled();
|
||||
}
|
||||
}
|
||||
const int linkWidth = skinConfInt["linkWidth"];
|
||||
const int leftSectionX = screenWidth / 2 + leftSection * linkWidth;
|
||||
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;
|
||||
@ -283,11 +282,6 @@ void Menu::setSectionIndex(int i) {
|
||||
i=0;
|
||||
iSection = i;
|
||||
|
||||
if (i>(int)iFirstDispSection+2)
|
||||
iFirstDispSection = i-2;
|
||||
else if (i<(int)iFirstDispSection)
|
||||
iFirstDispSection = i;
|
||||
|
||||
iLink = 0;
|
||||
iFirstDispRow = 0;
|
||||
}
|
||||
|
@ -42,12 +42,18 @@ private:
|
||||
GMenu2X *gmenu2x;
|
||||
Touchscreen &ts;
|
||||
int iSection, iLink;
|
||||
uint iFirstDispSection, iFirstDispRow;
|
||||
uint iFirstDispRow;
|
||||
std::vector<std::string> sections;
|
||||
std::vector< std::vector<Link*> > links;
|
||||
|
||||
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);
|
||||
|
||||
void readLinks();
|
||||
|
Loading…
Reference in New Issue
Block a user