Add pagination to game launcher - 4 games per page
- GameLauncher now displays only 4 games per page to keep menu in bounds - Added page navigation with page indicator (Page X/Y) - KEY0 navigates between pages and within page - KEY1 selects the highlighted game - Touch selection works on current page only - Helper methods: get_total_pages(), get_page_start_index(), get_page_end_index() - Updated both lib/ and emulator/ versions for consistency
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
GameLauncher::GameLauncher(uint16_t width, uint16_t height,
|
||||
LowLevelRenderer* renderer, LowLevelGUI* gui, InputManager* input_manager)
|
||||
: width(width), height(height), renderer(renderer), gui(gui), input_manager(input_manager),
|
||||
selected_index(0), selected_game(nullptr) {
|
||||
selected_index(0), selected_game(nullptr), current_page(0) {
|
||||
}
|
||||
|
||||
void GameLauncher::register_game(const char* name, const char* description,
|
||||
@@ -32,15 +32,23 @@ void GameLauncher::draw() {
|
||||
|
||||
renderer->set_font(&font_5x5_obj);
|
||||
|
||||
// Draw title
|
||||
renderer->draw_string_scaled(30, 40, "Select a Game:", 2);
|
||||
// Draw title with page indicator
|
||||
int total_pages = get_total_pages();
|
||||
char title[64];
|
||||
snprintf(title, sizeof(title), "Select a Game: (Page %d/%d)", current_page + 1, total_pages);
|
||||
renderer->draw_string_scaled(30, 40, title, 2);
|
||||
|
||||
// Draw game list with GUI buttons
|
||||
for (size_t i = 0; i < games.size(); i++) {
|
||||
int y = MENU_Y_START + (i * MENU_ITEM_HEIGHT);
|
||||
// Get games for current page
|
||||
int page_start = get_page_start_index();
|
||||
int page_end = get_page_end_index();
|
||||
|
||||
// Draw game list with GUI buttons for current page only
|
||||
for (int i = page_start; i < page_end && i < (int)games.size(); i++) {
|
||||
int item_index = i - page_start;
|
||||
int y = MENU_Y_START + (item_index * MENU_ITEM_HEIGHT);
|
||||
|
||||
// Draw button (pressed/highlighted if selected)
|
||||
bool is_selected = ((int)i == selected_index);
|
||||
bool is_selected = (i == selected_index);
|
||||
gui->draw_button(window, 20, y, games[i].name, is_selected, true);
|
||||
|
||||
// Draw description below button
|
||||
@@ -49,10 +57,17 @@ void GameLauncher::draw() {
|
||||
renderer->draw_string_scaled(50, y + 36, games[i].description, 1);
|
||||
}
|
||||
|
||||
// Draw instructions at bottom
|
||||
// Draw pagination controls at bottom
|
||||
char nav_text[128];
|
||||
if (total_pages > 1) {
|
||||
snprintf(nav_text, sizeof(nav_text), "KEY0: Next Page | KEY1: Select");
|
||||
} else {
|
||||
snprintf(nav_text, sizeof(nav_text), "KEY0: Navigate | KEY1: Select");
|
||||
}
|
||||
|
||||
const char* instructions;
|
||||
if (input_manager->has_buttons()) {
|
||||
instructions = "Touch game or use KEY0/KEY1";
|
||||
instructions = nav_text;
|
||||
} else {
|
||||
instructions = "Touch game to play";
|
||||
}
|
||||
@@ -60,6 +75,7 @@ void GameLauncher::draw() {
|
||||
renderer->draw_string_scaled(30, height - 35, instructions, 2);
|
||||
}
|
||||
|
||||
|
||||
bool GameLauncher::update(const InputEvent& event) {
|
||||
bool needs_refresh = false;
|
||||
|
||||
@@ -67,9 +83,13 @@ bool GameLauncher::update(const InputEvent& event) {
|
||||
case INPUT_TOUCH_DOWN: {
|
||||
printf("Touch at (%d,%d) in launcher\n", event.x, event.y);
|
||||
|
||||
// Check if touch is on a game entry
|
||||
for (size_t i = 0; i < games.size(); i++) {
|
||||
int y = MENU_Y_START + (i * MENU_ITEM_HEIGHT);
|
||||
// Check if touch is on a game entry for current page
|
||||
int page_start = get_page_start_index();
|
||||
int page_end = get_page_end_index();
|
||||
|
||||
for (int i = page_start; i < page_end && i < (int)games.size(); i++) {
|
||||
int item_index = i - page_start;
|
||||
int y = MENU_Y_START + (item_index * MENU_ITEM_HEIGHT);
|
||||
|
||||
// Touch area is the entire menu item
|
||||
if (event.y >= y - 5 && event.y < y + MENU_ITEM_HEIGHT - 5) {
|
||||
@@ -87,12 +107,42 @@ bool GameLauncher::update(const InputEvent& event) {
|
||||
}
|
||||
|
||||
case INPUT_BUTTON_0: {
|
||||
// Navigate menu
|
||||
if (games.size() > 0) {
|
||||
selected_index = (selected_index + 1) % games.size();
|
||||
needs_refresh = true;
|
||||
printf("Menu selection: %d (%s)\n", selected_index, games[selected_index].name);
|
||||
// Navigate within current page or switch pages
|
||||
int page_start = get_page_start_index();
|
||||
int page_end = get_page_end_index();
|
||||
int total_pages = get_total_pages();
|
||||
|
||||
// If multiple games on current page, navigate within page first
|
||||
if (page_end - page_start > 1) {
|
||||
// Move within current page
|
||||
int old_index = selected_index;
|
||||
selected_index++;
|
||||
if (selected_index >= page_end) {
|
||||
// Moving to next page
|
||||
if (current_page + 1 < total_pages) {
|
||||
current_page++;
|
||||
selected_index = get_page_start_index();
|
||||
} else {
|
||||
// Wrap to first page
|
||||
current_page = 0;
|
||||
selected_index = 0;
|
||||
}
|
||||
} else if (selected_index < page_start) {
|
||||
selected_index = page_start;
|
||||
}
|
||||
} else {
|
||||
// Single game on page, move to next page
|
||||
if (current_page + 1 < total_pages) {
|
||||
current_page++;
|
||||
selected_index = get_page_start_index();
|
||||
} else {
|
||||
// Wrap to first page
|
||||
current_page = 0;
|
||||
selected_index = 0;
|
||||
}
|
||||
}
|
||||
needs_refresh = true;
|
||||
printf("Menu selection: %d (%s), Page: %d\n", selected_index, games[selected_index].name, current_page);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -127,5 +177,19 @@ void GameLauncher::reset() {
|
||||
selected_game = nullptr;
|
||||
}
|
||||
selected_index = 0;
|
||||
current_page = 0;
|
||||
printf("Launcher reset - returning to menu\n");
|
||||
}
|
||||
|
||||
int GameLauncher::get_total_pages() const {
|
||||
if (games.empty()) return 1;
|
||||
return (games.size() + GAMES_PER_PAGE - 1) / GAMES_PER_PAGE;
|
||||
}
|
||||
|
||||
int GameLauncher::get_page_start_index() const {
|
||||
return current_page * GAMES_PER_PAGE;
|
||||
}
|
||||
|
||||
int GameLauncher::get_page_end_index() const {
|
||||
return (current_page + 1) * GAMES_PER_PAGE;
|
||||
}
|
||||
|
||||
@@ -95,11 +95,18 @@ private:
|
||||
std::vector<GameEntry> games;
|
||||
int selected_index; // Currently highlighted game
|
||||
Game* selected_game; // Currently running game (nullptr = in menu)
|
||||
int current_page; // Current page in pagination
|
||||
|
||||
// Menu layout constants
|
||||
static const int MENU_Y_START = 60;
|
||||
static const int MENU_ITEM_HEIGHT = 40;
|
||||
static const int MENU_PADDING = 10;
|
||||
static const int GAMES_PER_PAGE = 4;
|
||||
|
||||
// Helper functions for pagination
|
||||
int get_total_pages() const;
|
||||
int get_page_start_index() const;
|
||||
int get_page_end_index() const;
|
||||
};
|
||||
|
||||
#endif // GAME_LAUNCHER_H
|
||||
|
||||
Reference in New Issue
Block a user