1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-25 15:56:15 +02:00

Removed Button class

It was only used to share implementation between IconButton and Link.
However, there was only one non-trivial method, handleTS(), and that
method used a different code path for each use case: doubleClick was
always false for IconButton and always true for Link. So the total
amount of code was actually reduced by eliminating this code sharing.

The main motivation for this split is that I can now freely refactor
Link without having to worry about IconButton.
This commit is contained in:
Maarten ter Huurne 2013-08-14 04:21:56 +02:00
parent 6378fcfcd7
commit 742444c919
7 changed files with 112 additions and 182 deletions

View File

@ -1,6 +1,6 @@
bin_PROGRAMS = gmenu2x
gmenu2x_SOURCES = font.cpp button.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
gmenu2x_SOURCES = font.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
filelister.cpp gmenu2x.cpp iconbutton.cpp imagedialog.cpp inputdialog.cpp \
inputmanager.cpp linkapp.cpp link.cpp \
menu.cpp menusettingbool.cpp menusetting.cpp menusettingdir.cpp \
@ -15,7 +15,7 @@ gmenu2x_SOURCES = font.cpp button.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
imageio.cpp powersaver.cpp monitor.cpp mediamonitor.cpp clock.cpp \
helppopup.cpp contextmenu.cpp background.cpp battery.cpp
noinst_HEADERS = font.h button.h cpu.h dirdialog.h \
noinst_HEADERS = font.h cpu.h dirdialog.h \
filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.h \
inputdialog.h inputmanager.h linkapp.h link.h \
menu.h menusettingbool.h menusettingdir.h \

View File

@ -1,54 +0,0 @@
#include "button.h"
#include "delegate.h"
#include "gmenu2x.h"
using namespace std;
Button::Button(Touchscreen &ts_, bool doubleClick_)
: action(BIND(&Button::voidAction))
, rect((SDL_Rect) { 0, 0, 0, 0 })
, ts(ts_)
, doubleClick(doubleClick_)
, lastTick(0)
{
}
bool Button::isPressed() {
return ts.pressed() && ts.inRect(rect);
}
bool Button::isReleased() {
return ts.released() && ts.inRect(rect);
}
bool Button::handleTS() {
if (isReleased()) {
if (doubleClick) {
int tickNow = SDL_GetTicks();
if (tickNow - lastTick < 400) {
ts.setHandled();
action();
}
lastTick = tickNow;
} else {
ts.setHandled();
action();
}
return true;
}
return false;
}
SDL_Rect Button::getRect() {
return rect;
}
void Button::setSize(int w, int h) {
rect.w = w;
rect.h = h;
}
void Button::setPosition(int x, int y) {
rect.x = x;
rect.y = y;
}

View File

@ -1,56 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 by Massimiliano Torromeo *
* massimiliano.torromeo@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef BUTTON_H
#define BUTTON_H
#include "delegate.h"
#include <SDL.h>
class Touchscreen;
class Button {
public:
SDL_Rect getRect();
virtual void setPosition(int x, int y);
bool isPressed();
bool handleTS();
protected:
Button(Touchscreen &ts, bool doubleClick = false);
virtual ~Button() {};
void setSize(int w, int h);
function_t action;
SDL_Rect rect;
private:
bool isReleased();
void voidAction() {};
Touchscreen &ts;
bool doubleClick;
int lastTick;
};
#endif // BUTTON_H

View File

@ -6,48 +6,44 @@
using namespace std;
IconButton::IconButton(
GMenu2X *gmenu2x_, Touchscreen &ts_,
GMenu2X *gmenu2x, Touchscreen &ts,
const string &icon, const string &label)
: Button(ts_)
, gmenu2x(gmenu2x_)
: gmenu2x(gmenu2x)
, ts(ts)
, icon(icon)
, label(label)
, action([] {})
, rect({ 0, 0, 0, 0 })
{
this->icon = icon;
this->label = label;
iconSurface = gmenu2x->sc[icon];
recalcSize();
recalcRects();
}
void IconButton::setAction(function_t action) {
this->action = action;
}
void IconButton::setPosition(int x, int y) {
if (rect.x != x || rect.y != y) {
Button::setPosition(x,y);
recalcSize();
rect.x = x;
rect.y = y;
recalcRects();
}
}
void IconButton::paint() {
if (iconSurface) {
iconSurface->blit(gmenu2x->s, iconRect);
}
if (label != "") {
gmenu2x->s->write(gmenu2x->font, label, labelRect.x, labelRect.y,
Font::HAlignLeft, Font::VAlignMiddle);
}
}
void IconButton::recalcSize() {
void IconButton::recalcRects() {
Uint16 h = 0, w = 0;
if (iconSurface) {
w += iconSurface->width();
h += iconSurface->height();
iconRect = (SDL_Rect) { rect.x, rect.y, w, h };
} else {
iconRect = (SDL_Rect) { 0, 0, 0, 0 };
}
iconRect = { rect.x, rect.y, w, h };
if (label != "") {
uint margin = iconSurface ? 2 : 0;
labelRect = (SDL_Rect) {
if (!label.empty()) {
Uint16 margin = iconSurface ? 2 : 0;
labelRect = {
static_cast<Sint16>(iconRect.x + iconRect.w + margin),
static_cast<Sint16>(rect.y + h / 2),
static_cast<Uint16>(gmenu2x->font->getTextWidth(label)),
@ -56,9 +52,25 @@ void IconButton::recalcSize() {
w += margin + labelRect.w;
}
setSize(w, h);
rect.w = w;
rect.h = h;
}
void IconButton::setAction(function_t action) {
this->action = action;
bool IconButton::handleTS() {
if (ts.released() && ts.inRect(rect)) {
ts.setHandled();
action();
return true;
}
return false;
}
void IconButton::paint() {
if (iconSurface) {
iconSurface->blit(gmenu2x->s, iconRect);
}
if (!label.empty()) {
gmenu2x->s->write(gmenu2x->font, label, labelRect.x, labelRect.y,
Font::HAlignLeft, Font::VAlignMiddle);
}
}

View File

@ -1,36 +1,39 @@
#ifndef ICONBUTTON_H
#define ICONBUTTON_H
#include "button.h"
#include "delegate.h"
#include <SDL.h>
#include <string>
class GMenu2X;
class Surface;
class Touchscreen;
class IconButton : private Button {
class IconButton {
public:
IconButton(GMenu2X *gmenu2x, Touchscreen &ts,
const std::string &icon, const std::string &label = "");
virtual ~IconButton() {};
virtual void paint();
virtual void setPosition(int x, int y);
void setAction(function_t action);
// Expose some Button functionality:
SDL_Rect getRect() { return Button::getRect(); }
bool handleTS() { return Button::handleTS(); }
SDL_Rect getRect() { return rect; }
void setPosition(int x, int y);
bool handleTS();
void paint();
private:
void recalcSize();
void recalcRects();
GMenu2X *gmenu2x;
Touchscreen &ts;
std::string icon, label;
SDL_Rect iconRect, labelRect;
function_t action;
SDL_Rect rect, iconRect, labelRect;
Surface *iconSurface;
};

View File

@ -31,10 +31,13 @@
using namespace std;
Link::Link(GMenu2X *gmenu2x_, Touchscreen &ts, function_t action_)
: Button(ts, true)
, action(action_)
, gmenu2x(gmenu2x_)
Link::Link(GMenu2X *gmenu2x, Touchscreen &ts, function_t action)
: gmenu2x(gmenu2x)
, ts(ts)
, action(action)
, rect((SDL_Rect) { 0, 0, 0, 0 })
, lastTick(0)
{
edited = false;
iconPath = gmenu2x->sc.getSkinFilePath("icons/generic.png");
@ -44,6 +47,23 @@ Link::Link(GMenu2X *gmenu2x_, Touchscreen &ts, function_t action_)
updateSurfaces();
}
bool Link::isPressed() {
return ts.pressed() && ts.inRect(rect);
}
bool Link::handleTS() {
if (ts.released() && ts.inRect(rect)) {
int tickNow = SDL_GetTicks();
if (tickNow - lastTick < 400) {
ts.setHandled();
action();
}
lastTick = tickNow;
return true;
}
return false;
}
void Link::paint() {
if (iconSurface) {
iconSurface->blit(gmenu2x->s, iconX, rect.y+padding, 32,32);
@ -123,12 +143,14 @@ void Link::setIconPath(const string &icon) {
}
void Link::setSize(int w, int h) {
Button::setSize(w,h);
rect.w = w;
rect.h = h;
recalcCoordinates();
}
void Link::setPosition(int x, int y) {
Button::setPosition(x,y);
rect.x = x;
rect.y = y;
recalcCoordinates();
}

View File

@ -21,13 +21,14 @@
#ifndef LINK_H
#define LINK_H
#include "button.h"
#include "delegate.h"
#include <SDL.h>
#include <string>
class GMenu2X;
class Surface;
class Touchscreen;
/**
@ -35,29 +36,14 @@ Base class that represents a link on screen.
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
*/
class Link : private Button {
private:
void recalcCoordinates();
function_t action;
uint iconX, padding;
protected:
GMenu2X *gmenu2x;
bool edited;
std::string title, description, icon, iconPath;
Surface *iconSurface;
Surface *icon_hover;
virtual const std::string &searchIcon();
void setIconPath(const std::string &icon);
void updateSurfaces();
class Link {
public:
Link(GMenu2X *gmenu2x, Touchscreen &ts, function_t action);
virtual ~Link() {};
bool isPressed();
bool handleTS();
virtual void paint();
void paintHover();
@ -76,10 +62,27 @@ public:
void run();
// Expose some Button functionality:
//SDL_Rect getRect() { return Button::getRect(); }
bool isPressed() { return Button::isPressed(); }
bool handleTS() { return Button::handleTS(); }
protected:
GMenu2X *gmenu2x;
bool edited;
std::string title, description, icon, iconPath;
Surface *iconSurface;
Surface *icon_hover;
virtual const std::string &searchIcon();
void setIconPath(const std::string &icon);
void updateSurfaces();
private:
void recalcCoordinates();
Touchscreen &ts;
function_t action;
SDL_Rect rect;
uint iconX, padding;
int lastTick;
};
#endif