A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Robert Bieber
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "rbscene.h"
23#include "rbscreen.h"
24#include "rbviewport.h"
25#include "devicestate.h"
26
27#include <QPainter>
28#include <QFile>
29#include <QGraphicsSceneHoverEvent>
30#include <QGraphicsSceneMouseEvent>
31
32RBScreen::RBScreen(const RBRenderInfo& info, bool remote,
33 QGraphicsItem *parent)
34 :QGraphicsItem(parent), backdrop(0), project(project),
35 albumArt(0), customUI(0), defaultView(0), ax(false)
36{
37
38 setAcceptHoverEvents(true);
39
40 if(remote)
41 {
42 fullWidth = info.device()->data("remotewidth").toInt();
43 fullHeight = info.device()->data("remoteheight").toInt();
44 }
45 else
46 {
47 fullWidth = info.device()->data("screenwidth").toInt();
48 fullHeight = info.device()->data("screenheight").toInt();
49 }
50
51 QString bg = info.settings()->value("background color", "FFFFFF");
52 bgColor = stringToColor(bg, Qt::white);
53
54 QString fg = info.settings()->value("foreground color", "000000");
55 fgColor = stringToColor(fg, Qt::black);
56
57 settings = info.settings();
58
59 /* Loading backdrop if available */
60 themeBase = info.settings()->value("themebase", "");
61 QString backdropFile = info.settings()->value("backdrop", "");
62 backdropFile.replace("/.rockbox/backdrops/", "");
63
64 if(QFile::exists(themeBase + "/backdrops/" + backdropFile))
65 {
66 backdrop = new QPixmap(themeBase + "/backdrops/" + backdropFile);
67
68 /* If a backdrop has been found, use its width and height */
69 if(!backdrop->isNull())
70 {
71 fullWidth = backdrop->width();
72 fullHeight = backdrop->height();
73 }
74 else
75 {
76 delete backdrop;
77 backdrop = 0;
78 }
79 }
80
81 fonts.insert(0, new RBFont("Default"));
82 QString defaultFont = settings->value("font", "");
83 if(defaultFont != "")
84 {
85 defaultFont.replace("/.rockbox", settings->value("themebase", ""));
86 fonts.insert(1, new RBFont(defaultFont));
87 }
88
89 if(parent == 0)
90 {
91 width = fullWidth;
92 height = fullHeight;
93 }
94 else
95 {
96 width = parent->boundingRect().width();
97 height = parent->boundingRect().height();
98 }
99}
100
101RBScreen::~RBScreen()
102{
103 if(backdrop)
104 delete backdrop;
105
106 if(albumArt)
107 delete albumArt;
108
109 QMap<int, RBFont*>::iterator i;
110 for(i = fonts.begin(); i != fonts.end(); i++)
111 delete (*i);
112
113 QMap<QString, QList<RBViewport*>*>::iterator it;
114 for(it = namedViewports.begin(); it != namedViewports.end(); it++)
115 delete (*it);
116}
117
118QPainterPath RBScreen::shape() const
119{
120 QPainterPath retval;
121 retval.addRect(0, 0, width, height);
122 return retval;
123}
124
125QRectF RBScreen::boundingRect() const
126{
127 return QRectF(0, 0, width, height);
128}
129
130void RBScreen::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
131 QWidget *widget)
132{
133 if(parentItem() != 0)
134 return;
135
136 if(backdrop)
137 {
138 painter->drawPixmap(0, 0, width, height, *backdrop);
139 }
140 else
141 {
142 painter->fillRect(0, 0, width, height, bgColor);
143 }
144
145}
146
147void RBScreen::loadViewport(QString name, RBViewport *view)
148{
149 QList<RBViewport*>* list;
150 if(namedViewports.value(name, 0) == 0)
151 {
152 list = new QList<RBViewport*>;
153 list->append(view);
154 namedViewports.insert(name, list);
155 }
156 else
157 {
158 list = namedViewports.value(name, 0);
159 list->append(view);
160 }
161}
162
163void RBScreen::showViewport(QString name)
164{
165 if(namedViewports.value(name, 0) == 0)
166 {
167 displayedViewports.append(name);
168 return;
169 }
170
171 QList<RBViewport*>* list = namedViewports.value(name, 0);
172 for(int i = 0; i < list->count(); i++)
173 list->at(i)->show();
174}
175
176void RBScreen::loadFont(int id, RBFont* font)
177{
178 if(id < 2 || id > 9)
179 return;
180
181 fonts.insert(id, font);
182}
183
184RBFont* RBScreen::getFont(int id)
185{
186 if(fonts.value(id, 0) != 0)
187 return fonts.value(id);
188 else
189 return fonts.value(0, 0);
190}
191
192
193void RBScreen::setBackdrop(QString filename)
194{
195
196 if(backdrop)
197 delete backdrop;
198
199 filename = settings->value("imagepath", "") + "/" + filename;
200
201 if(QFile::exists(filename))
202 backdrop = new QPixmap(filename);
203 else
204 {
205 RBScene* s = dynamic_cast<RBScene*>(scene());
206 s->addWarning(QObject::tr("Image not found: ") + filename);
207 backdrop = 0;
208 }
209}
210
211void RBScreen::makeCustomUI(QString id)
212{
213 if(namedViewports.value(id, 0) != 0)
214 {
215 QMap<QString, QList<RBViewport*>*>::iterator i;
216 for(i = namedViewports.begin(); i != namedViewports.end(); i++)
217 for(int j = 0; j < (*i)->count(); j++)
218 (*i)->at(j)->clearCustomUI();
219 for(int i = 0; i < namedViewports.value(id)->count(); i++)
220 namedViewports.value(id)->at(i)->makeCustomUI();
221 for(int i = 0; i < namedViewports.value(id)->count(); i++)
222 namedViewports.value(id)->at(i)->show();
223
224 customUI = namedViewports.value(id)->at(0);
225 }
226}
227
228void RBScreen::endSbsRender()
229{
230 sbsChildren = childItems();
231
232 QList<int> keys = fonts.keys();
233 for(QList<int>::iterator i = keys.begin(); i != keys.end(); i++)
234 {
235 if(*i > 2)
236 fonts.remove(*i);
237 }
238
239 images.clear();
240 namedViewports.clear();
241 displayedViewports.clear();
242}
243
244void RBScreen::breakSBS()
245{
246 for(QList<QGraphicsItem*>::iterator i = sbsChildren.begin()
247 ; i != sbsChildren.end(); i++)
248 (*i)->hide();
249 if(defaultView)
250 defaultView->makeFullScreen();
251}
252
253QColor RBScreen::stringToColor(QString str, QColor fallback)
254{
255
256 QColor retval;
257
258 if(str.length() == 6)
259 {
260 for(int i = 0; i < 6; i++)
261 {
262 char c = str[i].toLatin1();
263 if(!((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') ||
264 isdigit(c)))
265 {
266 str = "";
267 break;
268 }
269 }
270 if(str != "")
271 retval = QColor("#" + str);
272 else
273 retval = fallback;
274 }
275 else if(str.length() == 1)
276 {
277 if(isdigit(str[0].toLatin1()) && str[0].toLatin1() <= '3')
278 {
279 int shade = 255 * (str[0].toLatin1() - '0') / 3;
280 retval = QColor(shade, shade, shade);
281 }
282 else
283 {
284 retval = fallback;
285 }
286 }
287 else
288 {
289 retval = fallback;
290 }
291
292 return retval;
293
294}
295
296void RBScreen::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
297{
298 RBScene* s = dynamic_cast<RBScene*>(scene());
299 QPoint p = event->scenePos().toPoint();
300 s->moveMouse("(" + QString::number(p.x()) + ", "
301 + QString::number(p.y()) + ")");
302
303 QGraphicsItem::hoverMoveEvent(event);
304}