mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-25 20:25:54 +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 \
|
||||
utilities.cpp wallpaperdialog.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 \
|
||||
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 \
|
||||
touchscreen.h translator.h utilities.h wallpaperdialog.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@
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "filelister.h"
|
||||
#include "font.h"
|
||||
#include "gmenu2x.h"
|
||||
#include "helppopup.h"
|
||||
#include "iconbutton.h"
|
||||
#include "inputdialog.h"
|
||||
#include "linkapp.h"
|
||||
@ -231,6 +232,7 @@ GMenu2X::GMenu2X()
|
||||
bg = NULL;
|
||||
font = NULL;
|
||||
menu = NULL;
|
||||
helpPopup = nullptr;
|
||||
btnContextMenu = nullptr;
|
||||
setSkin(confStr["skin"], !fileExists(confStr["wallpaper"]));
|
||||
initMenu();
|
||||
@ -278,6 +280,7 @@ GMenu2X::~GMenu2X() {
|
||||
quit();
|
||||
|
||||
delete menu;
|
||||
delete helpPopup;
|
||||
delete btnContextMenu;
|
||||
delete font;
|
||||
delete monitor;
|
||||
@ -398,6 +401,8 @@ void GMenu2X::initMenu() {
|
||||
|
||||
//DEBUG
|
||||
//menu->addLink( CARD_ROOT, "sample.pxml", "applications" );
|
||||
|
||||
layers.push_back(menu);
|
||||
}
|
||||
|
||||
void GMenu2X::about() {
|
||||
@ -603,7 +608,9 @@ void GMenu2X::paint() {
|
||||
//Background
|
||||
sc["bgmain"]->blit(s,0,0);
|
||||
|
||||
menu->paint(*s);
|
||||
for (Layer *layer : layers) {
|
||||
layer->paint(*s);
|
||||
}
|
||||
|
||||
LinkApp *linkApp = menu->selLinkApp();
|
||||
if (linkApp) {
|
||||
@ -627,22 +634,6 @@ void GMenu2X::paint() {
|
||||
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() {
|
||||
|
||||
batteryIcon = "imgs/battery/0.png";
|
||||
@ -651,8 +642,6 @@ void GMenu2X::main() {
|
||||
if (!fileExists(CARD_ROOT))
|
||||
CARD_ROOT = "";
|
||||
|
||||
bool helpDisplayed = false;
|
||||
|
||||
bool quit = false;
|
||||
while (!quit) {
|
||||
//check battery status every 60 seconds
|
||||
@ -670,27 +659,28 @@ void GMenu2X::main() {
|
||||
}
|
||||
|
||||
paint();
|
||||
if (helpDisplayed) {
|
||||
paintHelp();
|
||||
s->flip();
|
||||
while (input.waitForPressedButton() != InputManager::CANCEL) {}
|
||||
helpDisplayed=false;
|
||||
continue;
|
||||
}
|
||||
s->flip();
|
||||
|
||||
//touchscreen
|
||||
if (ts.available()) {
|
||||
ts.poll();
|
||||
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();
|
||||
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) {
|
||||
case InputManager::CANCEL:
|
||||
helpDisplayed=true;
|
||||
helpPopup = new HelpPopup(*this);
|
||||
layers.push_back(helpPopup);
|
||||
break;
|
||||
case InputManager::SETTINGS:
|
||||
options();
|
||||
@ -702,6 +692,19 @@ void GMenu2X::main() {
|
||||
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 Font;
|
||||
class HelpPopup;
|
||||
class IconButton;
|
||||
class Layer;
|
||||
class MediaMonitor;
|
||||
class Menu;
|
||||
class Surface;
|
||||
@ -66,9 +68,12 @@ class GMenu2X {
|
||||
private:
|
||||
Touchscreen ts;
|
||||
Menu *menu;
|
||||
HelpPopup *helpPopup;
|
||||
MediaMonitor *monitor;
|
||||
std::string batteryIcon;
|
||||
|
||||
std::vector<Layer *> layers;
|
||||
|
||||
/*!
|
||||
Retrieves the free disk space on the sd
|
||||
@return String containing a human readable representation of the free disk space
|
||||
@ -123,7 +128,6 @@ private:
|
||||
void initMenu();
|
||||
|
||||
void paint();
|
||||
void paintHelp();
|
||||
|
||||
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;
|
||||
const int topBarHeight = skinConfInt["topBarHeight"];
|
||||
const int screenWidth = gmenu2x->resX;
|
||||
@ -253,6 +253,7 @@ void Menu::handleTS() {
|
||||
setSectionIndex((iSection + numSections + i) % numSections);
|
||||
|
||||
ts.setHandled();
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint linksPerPage = linkColumns * linkRows;
|
||||
@ -266,6 +267,7 @@ void Menu::handleTS() {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ts.handled();
|
||||
}
|
||||
|
||||
/*====================================
|
||||
|
19
src/menu.h
19
src/menu.h
@ -22,7 +22,7 @@
|
||||
#define MENU_H
|
||||
|
||||
#include "delegate.h"
|
||||
#include "inputmanager.h"
|
||||
#include "layer.h"
|
||||
#include "link.h"
|
||||
|
||||
#include <string>
|
||||
@ -31,14 +31,14 @@
|
||||
class LinkApp;
|
||||
class GMenu2X;
|
||||
class Monitor;
|
||||
class Surface;
|
||||
|
||||
|
||||
/**
|
||||
Handles the menu structure
|
||||
|
||||
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
||||
*/
|
||||
class Menu {
|
||||
class Menu : public Layer {
|
||||
private:
|
||||
GMenu2X *gmenu2x;
|
||||
Touchscreen &ts;
|
||||
@ -84,7 +84,7 @@ private:
|
||||
|
||||
public:
|
||||
Menu(GMenu2X *gmenu2x, Touchscreen &ts);
|
||||
~Menu();
|
||||
virtual ~Menu();
|
||||
|
||||
#ifdef HAVE_LIBOPK
|
||||
void openPackage(std::string path, bool order = true);
|
||||
@ -107,15 +107,12 @@ public:
|
||||
void deleteSelectedSection();
|
||||
|
||||
void skinUpdated();
|
||||
void paint(Surface &s);
|
||||
|
||||
/**
|
||||
* Handles the pressing of the give button.
|
||||
* Returns true iff the event was consumed.
|
||||
*/
|
||||
bool handleButtonPress(InputManager::Button button);
|
||||
// Layer implementation:
|
||||
virtual void paint(Surface &s);
|
||||
virtual bool handleButtonPress(InputManager::Button button);
|
||||
virtual bool handleTouchscreen(Touchscreen &ts);
|
||||
|
||||
void handleTS();
|
||||
bool linkChangeSection(uint linkIndex, uint oldSectionIndex, uint newSectionIndex);
|
||||
|
||||
int selLinkIndex();
|
||||
|
Loading…
Reference in New Issue
Block a user