Date:2013-08-14 04:21:56 (10 years 7 months ago)
Author:Maarten ter Huurne
Commit:742444c9198c7336c267a360775c245823ed9b97
Message: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.
Files: src/Makefile.am (2 diffs)
src/button.cpp (1 diff)
src/button.h (1 diff)
src/iconbutton.cpp (2 diffs)
src/iconbutton.h (1 diff)
src/link.cpp (3 diffs)
src/link.h (3 diffs)

Change Details

src/Makefile.am
11bin_PROGRAMS = gmenu2x
22
3gmenu2x_SOURCES = font.cpp button.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
3gmenu2x_SOURCES = font.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
44    filelister.cpp gmenu2x.cpp iconbutton.cpp imagedialog.cpp inputdialog.cpp \
55    inputmanager.cpp linkapp.cpp link.cpp \
66    menu.cpp menusettingbool.cpp menusetting.cpp menusettingdir.cpp \
...... 
1515    imageio.cpp powersaver.cpp monitor.cpp mediamonitor.cpp clock.cpp \
1616    helppopup.cpp contextmenu.cpp background.cpp battery.cpp
1717
18noinst_HEADERS = font.h button.h cpu.h dirdialog.h \
18noinst_HEADERS = font.h cpu.h dirdialog.h \
1919    filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.h \
2020    inputdialog.h inputmanager.h linkapp.h link.h \
2121    menu.h menusettingbool.h menusettingdir.h \
src/button.cpp
1#include "button.h"
2#include "delegate.h"
3#include "gmenu2x.h"
4
5using namespace std;
6
7Button::Button(Touchscreen &ts_, bool doubleClick_)
8    : action(BIND(&Button::voidAction))
9    , rect((SDL_Rect) { 0, 0, 0, 0 })
10    , ts(ts_)
11    , doubleClick(doubleClick_)
12    , lastTick(0)
13{
14}
15
16bool Button::isPressed() {
17    return ts.pressed() && ts.inRect(rect);
18}
19
20bool Button::isReleased() {
21    return ts.released() && ts.inRect(rect);
22}
23
24bool Button::handleTS() {
25    if (isReleased()) {
26        if (doubleClick) {
27            int tickNow = SDL_GetTicks();
28            if (tickNow - lastTick < 400) {
29                ts.setHandled();
30                action();
31            }
32            lastTick = tickNow;
33        } else {
34            ts.setHandled();
35            action();
36        }
37        return true;
38    }
39    return false;
40}
41
42SDL_Rect Button::getRect() {
43    return rect;
44}
45
46void Button::setSize(int w, int h) {
47    rect.w = w;
48    rect.h = h;
49}
50
51void Button::setPosition(int x, int y) {
52    rect.x = x;
53    rect.y = y;
54}
src/button.h
1/***************************************************************************
2 * Copyright (C) 2006 by Massimiliano Torromeo *
3 * massimiliano.torromeo@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#ifndef BUTTON_H
22#define BUTTON_H
23
24#include "delegate.h"
25
26#include <SDL.h>
27
28class Touchscreen;
29
30class Button {
31public:
32    SDL_Rect getRect();
33    virtual void setPosition(int x, int y);
34
35    bool isPressed();
36    bool handleTS();
37
38protected:
39    Button(Touchscreen &ts, bool doubleClick = false);
40    virtual ~Button() {};
41
42    void setSize(int w, int h);
43
44    function_t action;
45    SDL_Rect rect;
46
47private:
48    bool isReleased();
49    void voidAction() {};
50
51    Touchscreen &ts;
52    bool doubleClick;
53    int lastTick;
54};
55
56#endif // BUTTON_H
src/iconbutton.cpp
66
77using namespace std;
88
9
910IconButton::IconButton(
10        GMenu2X *gmenu2x_, Touchscreen &ts_,
11        GMenu2X *gmenu2x, Touchscreen &ts,
1112        const string &icon, const string &label)
12    : Button(ts_)
13    , gmenu2x(gmenu2x_)
13    : gmenu2x(gmenu2x)
14    , ts(ts)
15    , icon(icon)
16    , label(label)
17    , action([] {})
18    , rect({ 0, 0, 0, 0 })
1419{
15    this->icon = icon;
16    this->label = label;
1720    iconSurface = gmenu2x->sc[icon];
18    recalcSize();
21    recalcRects();
1922}
2023
21void IconButton::setPosition(int x, int y) {
22    if (rect.x != x || rect.y != y) {
23        Button::setPosition(x,y);
24        recalcSize();
25    }
24void IconButton::setAction(function_t action) {
25    this->action = action;
2626}
2727
28void IconButton::paint() {
29    if (iconSurface) {
30        iconSurface->blit(gmenu2x->s, iconRect);
31    }
32    if (label != "") {
33        gmenu2x->s->write(gmenu2x->font, label, labelRect.x, labelRect.y,
34                Font::HAlignLeft, Font::VAlignMiddle);
28void IconButton::setPosition(int x, int y) {
29    if (rect.x != x || rect.y != y) {
30        rect.x = x;
31        rect.y = y;
32        recalcRects();
3533    }
3634}
3735
38void IconButton::recalcSize() {
36void IconButton::recalcRects() {
3937    Uint16 h = 0, w = 0;
4038    if (iconSurface) {
4139        w += iconSurface->width();
4240        h += iconSurface->height();
43        iconRect = (SDL_Rect) { rect.x, rect.y, w, h };
44    } else {
45        iconRect = (SDL_Rect) { 0, 0, 0, 0 };
4641    }
42    iconRect = { rect.x, rect.y, w, h };
4743
48    if (label != "") {
49        uint margin = iconSurface ? 2 : 0;
50        labelRect = (SDL_Rect) {
44    if (!label.empty()) {
45        Uint16 margin = iconSurface ? 2 : 0;
46        labelRect = {
5147            static_cast<Sint16>(iconRect.x + iconRect.w + margin),
5248            static_cast<Sint16>(rect.y + h / 2),
5349            static_cast<Uint16>(gmenu2x->font->getTextWidth(label)),
...... 
5652        w += margin + labelRect.w;
5753    }
5854
59    setSize(w, h);
55    rect.w = w;
56    rect.h = h;
6057}
6158
62void IconButton::setAction(function_t action) {
63    this->action = action;
59bool IconButton::handleTS() {
60    if (ts.released() && ts.inRect(rect)) {
61        ts.setHandled();
62        action();
63        return true;
64    }
65    return false;
66}
67
68void IconButton::paint() {
69    if (iconSurface) {
70        iconSurface->blit(gmenu2x->s, iconRect);
71    }
72    if (!label.empty()) {
73        gmenu2x->s->write(gmenu2x->font, label, labelRect.x, labelRect.y,
74                Font::HAlignLeft, Font::VAlignMiddle);
75    }
6476}
src/iconbutton.h
11#ifndef ICONBUTTON_H
22#define ICONBUTTON_H
33
4#include "button.h"
4#include "delegate.h"
55
6#include <SDL.h>
67#include <string>
78
89class GMenu2X;
910class Surface;
11class Touchscreen;
1012
11class IconButton : private Button {
13
14class IconButton {
1215public:
1316    IconButton(GMenu2X *gmenu2x, Touchscreen &ts,
1417            const std::string &icon, const std::string &label = "");
15    virtual ~IconButton() {};
1618
17    virtual void paint();
19    void setAction(function_t action);
1820
19    virtual void setPosition(int x, int y);
21    SDL_Rect getRect() { return rect; }
22    void setPosition(int x, int y);
2023
21    void setAction(function_t action);
24    bool handleTS();
2225
23    // Expose some Button functionality:
24    SDL_Rect getRect() { return Button::getRect(); }
25    bool handleTS() { return Button::handleTS(); }
26    void paint();
2627
2728private:
28    void recalcSize();
29    void recalcRects();
2930
3031    GMenu2X *gmenu2x;
32    Touchscreen &ts;
3133    std::string icon, label;
32    SDL_Rect iconRect, labelRect;
34    function_t action;
3335
36    SDL_Rect rect, iconRect, labelRect;
3437    Surface *iconSurface;
3538};
3639
src/link.cpp
3131
3232using namespace std;
3333
34Link::Link(GMenu2X *gmenu2x_, Touchscreen &ts, function_t action_)
35    : Button(ts, true)
36    , action(action_)
37    , gmenu2x(gmenu2x_)
34
35Link::Link(GMenu2X *gmenu2x, Touchscreen &ts, function_t action)
36    : gmenu2x(gmenu2x)
37    , ts(ts)
38    , action(action)
39    , rect((SDL_Rect) { 0, 0, 0, 0 })
40    , lastTick(0)
3841{
3942    edited = false;
4043    iconPath = gmenu2x->sc.getSkinFilePath("icons/generic.png");
...... 
4447    updateSurfaces();
4548}
4649
50bool Link::isPressed() {
51    return ts.pressed() && ts.inRect(rect);
52}
53
54bool Link::handleTS() {
55    if (ts.released() && ts.inRect(rect)) {
56        int tickNow = SDL_GetTicks();
57        if (tickNow - lastTick < 400) {
58            ts.setHandled();
59            action();
60        }
61        lastTick = tickNow;
62        return true;
63    }
64    return false;
65}
66
4767void Link::paint() {
4868    if (iconSurface) {
4969        iconSurface->blit(gmenu2x->s, iconX, rect.y+padding, 32,32);
...... 
123143}
124144
125145void Link::setSize(int w, int h) {
126    Button::setSize(w,h);
146    rect.w = w;
147    rect.h = h;
127148    recalcCoordinates();
128149}
129150
130151void Link::setPosition(int x, int y) {
131    Button::setPosition(x,y);
152    rect.x = x;
153    rect.y = y;
132154    recalcCoordinates();
133155}
134156
src/link.h
2121#ifndef LINK_H
2222#define LINK_H
2323
24#include "button.h"
2524#include "delegate.h"
2625
26#include <SDL.h>
2727#include <string>
2828
2929class GMenu2X;
3030class Surface;
31class Touchscreen;
3132
3233
3334/**
...... 
3536
3637    @author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
3738*/
38class Link : private Button {
39private:
40    void recalcCoordinates();
41
42    function_t action;
43    uint iconX, padding;
44
45protected:
46    GMenu2X *gmenu2x;
47    bool edited;
48    std::string title, description, icon, iconPath;
49
50    Surface *iconSurface;
51    Surface *icon_hover;
52
53    virtual const std::string &searchIcon();
54    void setIconPath(const std::string &icon);
55    void updateSurfaces();
56
39class Link {
5740public:
5841    Link(GMenu2X *gmenu2x, Touchscreen &ts, function_t action);
5942    virtual ~Link() {};
6043
44    bool isPressed();
45    bool handleTS();
46
6147    virtual void paint();
6248    void paintHover();
6349
...... 
7662
7763    void run();
7864
79    // Expose some Button functionality:
80    //SDL_Rect getRect() { return Button::getRect(); }
81    bool isPressed() { return Button::isPressed(); }
82    bool handleTS() { return Button::handleTS(); }
65protected:
66    GMenu2X *gmenu2x;
67    bool edited;
68    std::string title, description, icon, iconPath;
69
70    Surface *iconSurface;
71    Surface *icon_hover;
72
73    virtual const std::string &searchIcon();
74    void setIconPath(const std::string &icon);
75    void updateSurfaces();
76
77private:
78    void recalcCoordinates();
79
80    Touchscreen &ts;
81    function_t action;
82
83    SDL_Rect rect;
84    uint iconX, padding;
85    int lastTick;
8386};
8487
8588#endif

Archive Download the corresponding diff file



interactive