mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-22 23:52:48 +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)
|
: 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*> §ionLinks = links[iSection];
|
vector<Link*> §ionLinks = 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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user