1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-29 09:59:41 +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:
Maarten ter Huurne 2013-08-06 01:55:32 +02:00
parent 074668336e
commit 6d868a895a
8 changed files with 174 additions and 44 deletions

View File

@ -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@

View File

@ -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;
}
}
}
}

View File

@ -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
View 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
View 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
View 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

View File

@ -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();
}
/*====================================

View File

@ -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();