Root/src/contextmenu.cpp

Source at commit ef6d378c5e401954308260d1fe3a53429fa66f4c created 5 years 5 months ago.
By Maarten ter Huurne, Removed the "Rename section" option
1// Various authors.
2// License: GPL version 2 or later.
3
4#include "contextmenu.h"
5
6#include "gmenu2x.h"
7#include "linkapp.h"
8#include "menu.h"
9#include "utilities.h"
10
11#include <algorithm>
12#include <functional>
13
14
15struct ContextMenu::MenuOption {
16    typedef std::function<void(void)> Action;
17    MenuOption(std::string text, Action action)
18        : text(text), action(action) {}
19    std::string text;
20    Action action;
21};
22
23ContextMenu::ContextMenu(GMenu2X &gmenu2x, Menu &menu)
24    : gmenu2x(gmenu2x)
25    , menu(menu)
26    , selected(0)
27{
28    Translator &tr = gmenu2x.tr;
29    Font& font = *gmenu2x.font;
30    LinkApp* app = menu.selLinkApp();
31
32    // Init menu options:
33
34    options.push_back(std::make_shared<MenuOption>(
35            tr.translate("Add link in $1", menu.selSection().c_str(), NULL),
36            std::bind(&GMenu2X::addLink, &gmenu2x)));
37
38    if (app) {
39        if (!app->getManual().empty()) {
40            options.push_back(std::make_shared<MenuOption>(
41                    tr.translate("Show manual of $1",
42                        app->getTitle().c_str(), NULL),
43                    std::bind(&GMenu2X::showManual, &gmenu2x)));
44        }
45
46        /* FIXME(percuei): This permits to mask the "Edit link" entry
47         * on the contextual menu in case CPUFREQ support is
48         * not compiled in and the link corresponds to an OPK.
49         * This is not a good idea as it'll break things if
50         * a new config option is added to the contextual menu.
51         */
52        if (app->isEditable() && (
53                !app->isOpk()
54#if defined(ENABLE_CPUFREQ)
55                || true
56#endif
57                || !app->getSelectorDir().empty()
58                )) {
59            options.push_back(std::make_shared<MenuOption>(
60                    tr.translate("Edit $1", app->getTitle().c_str(), NULL),
61                    std::bind(&GMenu2X::editLink, &gmenu2x)));
62        }
63
64        if (app->isDeletable()) {
65            options.push_back(std::make_shared<MenuOption>(
66                    tr.translate("Delete $1", app->getTitle().c_str(), NULL),
67                    std::bind(&GMenu2X::deleteLink, &gmenu2x)));
68        }
69    }
70
71    options.push_back(std::make_shared<MenuOption>(
72            tr["Add section"],
73            std::bind(&GMenu2X::addSection, &gmenu2x)));
74    options.push_back(std::make_shared<MenuOption>(
75            tr["Delete section"],
76            std::bind(&GMenu2X::deleteSection, &gmenu2x)));
77
78    // Compute bounding box.
79    int w = 0;
80    for (auto option : options) {
81        w = std::max(w, font.getTextWidth(option->text));
82    }
83    w += 23;
84    const int h = (font.getLineSpacing() + 2) * options.size() + 8;
85    box = {
86        static_cast<Sint16>((gmenu2x.resX - w) / 2),
87        static_cast<Sint16>((gmenu2x.resY - h) / 2),
88        static_cast<Uint16>(w),
89        static_cast<Uint16>(h)
90    };
91
92    // Init background fade animation.
93    tickStart = SDL_GetTicks();
94    fadeAlpha = 0;
95}
96
97bool ContextMenu::runAnimations()
98{
99    if (fadeAlpha < 200) {
100        const long tickNow = SDL_GetTicks();
101        fadeAlpha = intTransition(0, 200, tickStart, 500, tickNow);
102    }
103    return fadeAlpha < 200;
104}
105
106void ContextMenu::paint(Surface &s)
107{
108    Font& font = *gmenu2x.font;
109
110    // Darken background.
111    s.box(0, 0, gmenu2x.resX, gmenu2x.resY, 0, 0, 0, fadeAlpha);
112
113    // Draw popup box.
114    s.box(box, gmenu2x.skinConfColors[COLOR_MESSAGE_BOX_BG]);
115    s.rectangle(box.x + 2, box.y + 2, box.w - 4, box.h - 4,
116            gmenu2x.skinConfColors[COLOR_MESSAGE_BOX_BORDER]);
117
118    // Draw selection background.
119    const int h = font.getLineSpacing();
120    SDL_Rect selbox = {
121        static_cast<Sint16>(box.x + 4),
122        static_cast<Sint16>(box.y + 4 + (h + 2) * selected),
123        static_cast<Uint16>(box.w - 8),
124        static_cast<Uint16>(h + 2)
125    };
126    s.box(selbox, gmenu2x.skinConfColors[COLOR_MESSAGE_BOX_SELECTION]);
127
128    // List options.
129    for (uint i = 0; i < options.size(); i++) {
130        font.write(s, options[i]->text, box.x + 12, box.y + 5 + (h + 2) * i,
131                Font::HAlignLeft, Font::VAlignTop);
132    }
133}
134
135bool ContextMenu::handleButtonPress(InputManager::Button button) {
136    switch (button) {
137        case InputManager::MENU:
138            dismiss();
139            break;
140        case InputManager::UP:
141            selected--;
142            if (selected < 0) selected = options.size() - 1;
143            break;
144        case InputManager::DOWN:
145            selected++;
146            if (selected >= static_cast<int>(options.size())) selected = 0;
147            break;
148        case InputManager::ACCEPT:
149            options[selected]->action();
150            dismiss();
151            break;
152        default:
153            break;
154    }
155    return true;
156}
157

Archive Download this file



interactive