mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-29 12:18:27 +02:00
Implemented layer system for painting and events
The long term goal is to be able to use a single event loop regardless of which submenu or alternative mode is active.
This commit is contained in:
parent
074668336e
commit
6d868a895a
@ -12,7 +12,8 @@ gmenu2x_SOURCES = font.cpp button.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
|
|||||||
textdialog.cpp textmanualdialog.cpp touchscreen.cpp translator.cpp \
|
textdialog.cpp textmanualdialog.cpp touchscreen.cpp translator.cpp \
|
||||||
utilities.cpp wallpaperdialog.cpp \
|
utilities.cpp wallpaperdialog.cpp \
|
||||||
browsedialog.cpp buttonbox.cpp dialog.cpp \
|
browsedialog.cpp buttonbox.cpp dialog.cpp \
|
||||||
imageio.cpp powersaver.cpp monitor.cpp mediamonitor.cpp clock.cpp
|
imageio.cpp powersaver.cpp monitor.cpp mediamonitor.cpp clock.cpp \
|
||||||
|
helppopup.cpp
|
||||||
|
|
||||||
noinst_HEADERS = font.h button.h cpu.h dirdialog.h \
|
noinst_HEADERS = font.h button.h cpu.h dirdialog.h \
|
||||||
filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.h \
|
filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.h \
|
||||||
@ -25,7 +26,8 @@ noinst_HEADERS = font.h button.h cpu.h dirdialog.h \
|
|||||||
surfacecollection.h surface.h textdialog.h textmanualdialog.h \
|
surfacecollection.h surface.h textdialog.h textmanualdialog.h \
|
||||||
touchscreen.h translator.h utilities.h wallpaperdialog.h \
|
touchscreen.h translator.h utilities.h wallpaperdialog.h \
|
||||||
browsedialog.h buttonbox.h dialog.h \
|
browsedialog.h buttonbox.h dialog.h \
|
||||||
imageio.h powersaver.h monitor.h mediamonitor.h clock.h
|
imageio.h powersaver.h monitor.h mediamonitor.h clock.h \
|
||||||
|
layer.h helppopup.h
|
||||||
|
|
||||||
AM_CFLAGS= @CFLAGS@ @SDL_CFLAGS@
|
AM_CFLAGS= @CFLAGS@ @SDL_CFLAGS@
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "filelister.h"
|
#include "filelister.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "gmenu2x.h"
|
#include "gmenu2x.h"
|
||||||
|
#include "helppopup.h"
|
||||||
#include "iconbutton.h"
|
#include "iconbutton.h"
|
||||||
#include "inputdialog.h"
|
#include "inputdialog.h"
|
||||||
#include "linkapp.h"
|
#include "linkapp.h"
|
||||||
@ -231,6 +232,7 @@ GMenu2X::GMenu2X()
|
|||||||
bg = NULL;
|
bg = NULL;
|
||||||
font = NULL;
|
font = NULL;
|
||||||
menu = NULL;
|
menu = NULL;
|
||||||
|
helpPopup = nullptr;
|
||||||
btnContextMenu = nullptr;
|
btnContextMenu = nullptr;
|
||||||
setSkin(confStr["skin"], !fileExists(confStr["wallpaper"]));
|
setSkin(confStr["skin"], !fileExists(confStr["wallpaper"]));
|
||||||
initMenu();
|
initMenu();
|
||||||
@ -278,6 +280,7 @@ GMenu2X::~GMenu2X() {
|
|||||||
quit();
|
quit();
|
||||||
|
|
||||||
delete menu;
|
delete menu;
|
||||||
|
delete helpPopup;
|
||||||
delete btnContextMenu;
|
delete btnContextMenu;
|
||||||
delete font;
|
delete font;
|
||||||
delete monitor;
|
delete monitor;
|
||||||
@ -398,6 +401,8 @@ void GMenu2X::initMenu() {
|
|||||||
|
|
||||||
//DEBUG
|
//DEBUG
|
||||||
//menu->addLink( CARD_ROOT, "sample.pxml", "applications" );
|
//menu->addLink( CARD_ROOT, "sample.pxml", "applications" );
|
||||||
|
|
||||||
|
layers.push_back(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMenu2X::about() {
|
void GMenu2X::about() {
|
||||||
@ -603,7 +608,9 @@ void GMenu2X::paint() {
|
|||||||
//Background
|
//Background
|
||||||
sc["bgmain"]->blit(s,0,0);
|
sc["bgmain"]->blit(s,0,0);
|
||||||
|
|
||||||
menu->paint(*s);
|
for (Layer *layer : layers) {
|
||||||
|
layer->paint(*s);
|
||||||
|
}
|
||||||
|
|
||||||
LinkApp *linkApp = menu->selLinkApp();
|
LinkApp *linkApp = menu->selLinkApp();
|
||||||
if (linkApp) {
|
if (linkApp) {
|
||||||
@ -627,22 +634,6 @@ void GMenu2X::paint() {
|
|||||||
Font::HAlignCenter, Font::VAlignMiddle);
|
Font::HAlignCenter, Font::VAlignMiddle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMenu2X::paintHelp() {
|
|
||||||
//On Screen Help
|
|
||||||
int helpBoxHeight = 154;
|
|
||||||
s->box(10,50,300,helpBoxHeight+4, skinConfColors[COLOR_MESSAGE_BOX_BG]);
|
|
||||||
s->rectangle( 12,52,296,helpBoxHeight,
|
|
||||||
skinConfColors[COLOR_MESSAGE_BOX_BORDER] );
|
|
||||||
s->write( font, tr["CONTROLS"], 20, 60 );
|
|
||||||
#if defined(PLATFORM_A320) || defined(PLATFORM_GCW0)
|
|
||||||
s->write( font, tr["A: Launch link / Confirm action"], 20, 80 );
|
|
||||||
s->write( font, tr["B: Show this help menu"], 20, 95 );
|
|
||||||
s->write( font, tr["L, R: Change section"], 20, 110 );
|
|
||||||
s->write( font, tr["SELECT: Show contextual menu"], 20, 155 );
|
|
||||||
s->write( font, tr["START: Show options menu"], 20, 170 );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void GMenu2X::main() {
|
void GMenu2X::main() {
|
||||||
|
|
||||||
batteryIcon = "imgs/battery/0.png";
|
batteryIcon = "imgs/battery/0.png";
|
||||||
@ -651,8 +642,6 @@ void GMenu2X::main() {
|
|||||||
if (!fileExists(CARD_ROOT))
|
if (!fileExists(CARD_ROOT))
|
||||||
CARD_ROOT = "";
|
CARD_ROOT = "";
|
||||||
|
|
||||||
bool helpDisplayed = false;
|
|
||||||
|
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
//check battery status every 60 seconds
|
//check battery status every 60 seconds
|
||||||
@ -670,27 +659,28 @@ void GMenu2X::main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
paint();
|
paint();
|
||||||
if (helpDisplayed) {
|
|
||||||
paintHelp();
|
|
||||||
s->flip();
|
|
||||||
while (input.waitForPressedButton() != InputManager::CANCEL) {}
|
|
||||||
helpDisplayed=false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
s->flip();
|
s->flip();
|
||||||
|
|
||||||
//touchscreen
|
//touchscreen
|
||||||
if (ts.available()) {
|
if (ts.available()) {
|
||||||
ts.poll();
|
ts.poll();
|
||||||
btnContextMenu->handleTS();
|
btnContextMenu->handleTS();
|
||||||
menu->handleTS();
|
bool handled = false;
|
||||||
|
for (auto it = layers.rbegin(); !handled && it != layers.rend(); ++it) {
|
||||||
|
handled = (*it)->handleTouchscreen(ts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InputManager::Button button = input.waitForPressedButton();
|
InputManager::Button button = input.waitForPressedButton();
|
||||||
if (!menu->handleButtonPress(button)) {
|
bool handled = false;
|
||||||
|
for (auto it = layers.rbegin(); !handled && it != layers.rend(); ++it) {
|
||||||
|
handled = (*it)->handleButtonPress(button);
|
||||||
|
}
|
||||||
|
if (!handled) {
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case InputManager::CANCEL:
|
case InputManager::CANCEL:
|
||||||
helpDisplayed=true;
|
helpPopup = new HelpPopup(*this);
|
||||||
|
layers.push_back(helpPopup);
|
||||||
break;
|
break;
|
||||||
case InputManager::SETTINGS:
|
case InputManager::SETTINGS:
|
||||||
options();
|
options();
|
||||||
@ -702,6 +692,19 @@ void GMenu2X::main() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto it = layers.begin(); it != layers.end(); ) {
|
||||||
|
Layer *layer = *it;
|
||||||
|
if (layer->wasDismissed()) {
|
||||||
|
it = layers.erase(it);
|
||||||
|
if (layer == helpPopup) {
|
||||||
|
delete helpPopup;
|
||||||
|
helpPopup = nullptr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,9 @@
|
|||||||
|
|
||||||
class Button;
|
class Button;
|
||||||
class Font;
|
class Font;
|
||||||
|
class HelpPopup;
|
||||||
class IconButton;
|
class IconButton;
|
||||||
|
class Layer;
|
||||||
class MediaMonitor;
|
class MediaMonitor;
|
||||||
class Menu;
|
class Menu;
|
||||||
class Surface;
|
class Surface;
|
||||||
@ -66,9 +68,12 @@ class GMenu2X {
|
|||||||
private:
|
private:
|
||||||
Touchscreen ts;
|
Touchscreen ts;
|
||||||
Menu *menu;
|
Menu *menu;
|
||||||
|
HelpPopup *helpPopup;
|
||||||
MediaMonitor *monitor;
|
MediaMonitor *monitor;
|
||||||
std::string batteryIcon;
|
std::string batteryIcon;
|
||||||
|
|
||||||
|
std::vector<Layer *> layers;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Retrieves the free disk space on the sd
|
Retrieves the free disk space on the sd
|
||||||
@return String containing a human readable representation of the free disk space
|
@return String containing a human readable representation of the free disk space
|
||||||
@ -123,7 +128,6 @@ private:
|
|||||||
void initMenu();
|
void initMenu();
|
||||||
|
|
||||||
void paint();
|
void paint();
|
||||||
void paintHelp();
|
|
||||||
|
|
||||||
void showManual();
|
void showManual();
|
||||||
|
|
||||||
|
46
src/helppopup.cpp
Normal file
46
src/helppopup.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Various authors.
|
||||||
|
// License: GPL version 2 or later.
|
||||||
|
|
||||||
|
#include "helppopup.h"
|
||||||
|
|
||||||
|
#include "gmenu2x.h"
|
||||||
|
|
||||||
|
|
||||||
|
HelpPopup::HelpPopup(GMenu2X &gmenu2x)
|
||||||
|
: gmenu2x(gmenu2x)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void HelpPopup::paint(Surface &s) {
|
||||||
|
Font *font = gmenu2x.font;
|
||||||
|
Translator &tr = gmenu2x.tr;
|
||||||
|
int helpBoxHeight = 154;
|
||||||
|
|
||||||
|
s.box(10, 50, 300, helpBoxHeight + 4,
|
||||||
|
gmenu2x.skinConfColors[COLOR_MESSAGE_BOX_BG]);
|
||||||
|
s.rectangle(12, 52, 296, helpBoxHeight,
|
||||||
|
gmenu2x.skinConfColors[COLOR_MESSAGE_BOX_BORDER]);
|
||||||
|
s.write(font, tr["CONTROLS"], 20, 60);
|
||||||
|
#if defined(PLATFORM_A320) || defined(PLATFORM_GCW0)
|
||||||
|
s.write(font, tr["A: Launch link / Confirm action"], 20, 80);
|
||||||
|
s.write(font, tr["B: Show this help menu"], 20, 95);
|
||||||
|
s.write(font, tr["L, R: Change section"], 20, 110);
|
||||||
|
s.write(font, tr["SELECT: Show contextual menu"], 20, 155);
|
||||||
|
s.write(font, tr["START: Show options menu"], 20, 170);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HelpPopup::handleButtonPress(InputManager::Button button) {
|
||||||
|
if (button == InputManager::CANCEL) {
|
||||||
|
dismissed = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HelpPopup::handleTouchscreen(Touchscreen &ts) {
|
||||||
|
if (ts.pressed()) {
|
||||||
|
dismissed = true;
|
||||||
|
ts.setHandled();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
28
src/helppopup.h
Normal file
28
src/helppopup.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Various authors.
|
||||||
|
// License: GPL version 2 or later.
|
||||||
|
|
||||||
|
#ifndef HELPPOPUP_H
|
||||||
|
#define HELPPOPUP_H
|
||||||
|
|
||||||
|
#include "layer.h"
|
||||||
|
|
||||||
|
class GMenu2X;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A passive dialog containing some helpful text for the user.
|
||||||
|
*/
|
||||||
|
class HelpPopup : public Layer {
|
||||||
|
public:
|
||||||
|
HelpPopup(GMenu2X &gmenu2x);
|
||||||
|
|
||||||
|
// Layer implementation:
|
||||||
|
virtual void paint(Surface &s);
|
||||||
|
virtual bool handleButtonPress(InputManager::Button button);
|
||||||
|
virtual bool handleTouchscreen(Touchscreen &ts);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GMenu2X &gmenu2x;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HELPPOPUP_H
|
48
src/layer.h
Normal file
48
src/layer.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// (c) 2013 Maarten ter Huurne <maarten@treewalker.org>
|
||||||
|
// License: GPL version 2 or later.
|
||||||
|
|
||||||
|
#ifndef LAYER_H
|
||||||
|
#define LAYER_H
|
||||||
|
|
||||||
|
#include "inputmanager.h"
|
||||||
|
|
||||||
|
class Surface;
|
||||||
|
class Touchscreen;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for UI layers.
|
||||||
|
* A layer handles both painting and input events.
|
||||||
|
*/
|
||||||
|
class Layer {
|
||||||
|
public:
|
||||||
|
virtual ~Layer() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paints this layer on the given surface.
|
||||||
|
*/
|
||||||
|
virtual void paint(Surface &s) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the pressing of the give button.
|
||||||
|
* Returns true iff the button press event was fully handled by this layer.
|
||||||
|
*/
|
||||||
|
virtual bool handleButtonPress(InputManager::Button button) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the touch screen.
|
||||||
|
* Only called if there is a touch screen available.
|
||||||
|
* Returns true iff the touch screen was fully handled by this layer.
|
||||||
|
*/
|
||||||
|
virtual bool handleTouchscreen(Touchscreen &ts) = 0;
|
||||||
|
|
||||||
|
bool wasDismissed() { return dismissed; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Set this to true to request the layer to be removed from the stack.
|
||||||
|
*/
|
||||||
|
bool dismissed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LAYER_H
|
@ -235,7 +235,7 @@ bool Menu::handleButtonPress(InputManager::Button button) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::handleTS() {
|
bool Menu::handleTouchscreen(Touchscreen &ts) {
|
||||||
ConfIntHash &skinConfInt = gmenu2x->skinConfInt;
|
ConfIntHash &skinConfInt = gmenu2x->skinConfInt;
|
||||||
const int topBarHeight = skinConfInt["topBarHeight"];
|
const int topBarHeight = skinConfInt["topBarHeight"];
|
||||||
const int screenWidth = gmenu2x->resX;
|
const int screenWidth = gmenu2x->resX;
|
||||||
@ -253,6 +253,7 @@ void Menu::handleTS() {
|
|||||||
setSectionIndex((iSection + numSections + i) % numSections);
|
setSectionIndex((iSection + numSections + i) % numSections);
|
||||||
|
|
||||||
ts.setHandled();
|
ts.setHandled();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint linksPerPage = linkColumns * linkRows;
|
const uint linksPerPage = linkColumns * linkRows;
|
||||||
@ -266,6 +267,7 @@ void Menu::handleTS() {
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
return ts.handled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*====================================
|
/*====================================
|
||||||
|
19
src/menu.h
19
src/menu.h
@ -22,7 +22,7 @@
|
|||||||
#define MENU_H
|
#define MENU_H
|
||||||
|
|
||||||
#include "delegate.h"
|
#include "delegate.h"
|
||||||
#include "inputmanager.h"
|
#include "layer.h"
|
||||||
#include "link.h"
|
#include "link.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -31,14 +31,14 @@
|
|||||||
class LinkApp;
|
class LinkApp;
|
||||||
class GMenu2X;
|
class GMenu2X;
|
||||||
class Monitor;
|
class Monitor;
|
||||||
class Surface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Handles the menu structure
|
Handles the menu structure
|
||||||
|
|
||||||
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
||||||
*/
|
*/
|
||||||
class Menu {
|
class Menu : public Layer {
|
||||||
private:
|
private:
|
||||||
GMenu2X *gmenu2x;
|
GMenu2X *gmenu2x;
|
||||||
Touchscreen &ts;
|
Touchscreen &ts;
|
||||||
@ -84,7 +84,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Menu(GMenu2X *gmenu2x, Touchscreen &ts);
|
Menu(GMenu2X *gmenu2x, Touchscreen &ts);
|
||||||
~Menu();
|
virtual ~Menu();
|
||||||
|
|
||||||
#ifdef HAVE_LIBOPK
|
#ifdef HAVE_LIBOPK
|
||||||
void openPackage(std::string path, bool order = true);
|
void openPackage(std::string path, bool order = true);
|
||||||
@ -107,15 +107,12 @@ public:
|
|||||||
void deleteSelectedSection();
|
void deleteSelectedSection();
|
||||||
|
|
||||||
void skinUpdated();
|
void skinUpdated();
|
||||||
void paint(Surface &s);
|
|
||||||
|
|
||||||
/**
|
// Layer implementation:
|
||||||
* Handles the pressing of the give button.
|
virtual void paint(Surface &s);
|
||||||
* Returns true iff the event was consumed.
|
virtual bool handleButtonPress(InputManager::Button button);
|
||||||
*/
|
virtual bool handleTouchscreen(Touchscreen &ts);
|
||||||
bool handleButtonPress(InputManager::Button button);
|
|
||||||
|
|
||||||
void handleTS();
|
|
||||||
bool linkChangeSection(uint linkIndex, uint oldSectionIndex, uint newSectionIndex);
|
bool linkChangeSection(uint linkIndex, uint oldSectionIndex, uint newSectionIndex);
|
||||||
|
|
||||||
int selLinkIndex();
|
int selLinkIndex();
|
||||||
|
Loading…
Reference in New Issue
Block a user