• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 4638737805

pending completion
4638737805

push

github

Georg Zotti
Fix template string for width estimate

1 of 1 new or added line in 1 file covered. (100.0%)

14721 of 124748 relevant lines covered (11.8%)

26313.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/gui/StelGuiItems.cpp
1
/*
2
 * Stellarium
3
 * Copyright (C) 2008 Fabien Chereau
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (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 Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18
 */
19

20
#include "StelApp.hpp"
21
#include "StelCore.hpp"
22

23
#include "StelUtils.hpp"
24
#include "SolarSystem.hpp"
25
#include "StelGuiItems.hpp"
26
#include "StelGui.hpp"
27
#include "StelLocaleMgr.hpp"
28
#include "StelLocation.hpp"
29
#include "StelMainView.hpp"
30
#include "StelMovementMgr.hpp"
31
#include "StelModuleMgr.hpp"
32
#include "StelActionMgr.hpp"
33
#include "StelProgressController.hpp"
34
#include "StelPropertyMgr.hpp"
35
#include "StelObserver.hpp"
36
#include "SkyGui.hpp"
37
#include "EphemWrapper.hpp"
38

39
#include <QPainter>
40
#include <QGraphicsScene>
41
#include <QGraphicsView>
42
#include <QGraphicsLineItem>
43
#include <QRectF>
44
#include <QDebug>
45
#include <QScreen>
46
#include <QGraphicsSceneMouseEvent>
47
#include <QGraphicsTextItem>
48
#include <QTimeLine>
49
#include <QMouseEvent>
50
#include <QPixmapCache>
51
#include <QProgressBar>
52
#include <QGraphicsWidget>
53
#include <QGraphicsProxyWidget>
54
#include <QGraphicsLinearLayout>
55
#include <QSettings>
56
#include <QGuiApplication>
57

58
// Inspired by text-use-opengl-buffer branch: work around font problems in GUI buttons.
59
// May be useful in other broken OpenGL font situations. RasPi necessity as of 2016-03-26. Mesa 13 (2016-11) has finally fixed this on RasPi(VC4).
60
QPixmap getTextPixmap(const QString& str, QFont font)
×
61
{
62
        // Render the text str into a QPixmap.
63
        QRect strRect = QFontMetrics(font).boundingRect(str);
×
64
        qDebug() << "getTextPixMap " << str << strRect;
×
65
        int w = static_cast<int>(1.02f*static_cast<float>(strRect.width()))+1;
×
66
        int h = strRect.height();
×
67

68
        QPixmap strPixmap(w, h);
×
69
        strPixmap.fill(Qt::transparent);
×
70
        QPainter painter(&strPixmap);
×
71
        font.setStyleStrategy(QFont::NoAntialias); // else: font problems on RasPi20160326
×
72
        painter.setFont(font);
×
73
        //painter.setRenderHints(QPainter::TextAntialiasing);
74
        painter.setPen(Qt::white);
×
75
        painter.drawText(-strRect.x(), -strRect.y(), str);
×
76
        return strPixmap;
×
77
}
×
78

79
void StelButton::initCtor(const QPixmap& apixOn,
×
80
                                                  const QPixmap& apixOff,
81
                                                  const QPixmap& apixNoChange,
82
                                                  const QPixmap& apixHover,
83
                                                  StelAction* anAction,
84
                                                  StelAction* otherAction,
85
                                                  bool noBackground,
86
                                                  bool isTristate)
87
{
88
        pixOn = apixOn;
×
89
        pixOff = apixOff;
×
90
        pixHover = apixHover;
×
91
        pixNoChange = apixNoChange;
×
92

93
        if(!pixmapsScale)
×
94
        {
95
                pixmapsScale = StelApp::getInstance().getSettings()->value("gui/pixmaps_scale", GUI_INPUT_PIXMAPS_SCALE).toDouble();
×
96
        }
97
        if(pixmapsScale != GUI_INPUT_PIXMAPS_SCALE)
×
98
        {
99
                const auto scale = pixmapsScale/GUI_INPUT_PIXMAPS_SCALE;
×
100
                pixOn = pixOn.scaled(pixOn.size()*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
×
101
                pixOff = pixOff.scaled(pixOff.size()*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
×
102
                if(!pixHover.isNull())
×
103
                        pixHover = pixHover.scaled(pixHover.size()*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
×
104
                if(!pixNoChange.isNull())
×
105
                        pixNoChange = pixNoChange.scaled(pixNoChange.size()*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
×
106
        }
107
        pixOn.setDevicePixelRatio(pixmapsScale);
×
108
        pixOff.setDevicePixelRatio(pixmapsScale);
×
109
        pixHover.setDevicePixelRatio(pixmapsScale);
×
110
        pixNoChange.setDevicePixelRatio(pixmapsScale);
×
111

112
        noBckground = noBackground;
×
113
        isTristate_ = isTristate;
×
114
        opacity = 1.;
×
115
        hoverOpacity = 0.;
×
116
        action = anAction;
×
117
        secondAction = otherAction;
×
118
        checked = false;
×
119
        flagChangeFocus = false;
×
120

121
        //Q_ASSERT(!pixOn.isNull());
122
        ///Q_ASSERT(!pixOff.isNull());
123

124
        if (isTristate_)
×
125
        {
126
                Q_ASSERT(!pixNoChange.isNull());
×
127
        }
128

129
        setShapeMode(QGraphicsPixmapItem::BoundingRectShape);        
×
130
        setAcceptHoverEvents(true);
×
131
        timeLine = new QTimeLine(250, this);
×
132
        timeLine->setEasingCurve(QEasingCurve(QEasingCurve::OutCurve));
×
133
        connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animValueChanged(qreal)));
×
134
        connect(&StelMainView::getInstance(), SIGNAL(updateIconsRequested()), this, SLOT(updateIcon()));  // Not sure if this is ever called?
×
135
        StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
136
        connect(gui, SIGNAL(flagUseButtonsBackgroundChanged(bool)), this, SLOT(updateIcon()));
×
137

138
        if (action!=nullptr)
×
139
        {
140
                if (action->isCheckable())
×
141
                {
142
                        setChecked(action->isChecked());
×
143
                        connect(action, SIGNAL(toggled(bool)), this, SLOT(setChecked(bool)));
×
144
                        connect(this, SIGNAL(toggled(bool)), action, SLOT(setChecked(bool)));
×
145
                }
146
                else
147
                {
148
                        QObject::connect(this, SIGNAL(triggered()), action, SLOT(trigger()));
×
149
                }
150
        }
151
        if (secondAction!=nullptr)
×
152
        {
153
                        QObject::connect(this, SIGNAL(triggeredRight()), secondAction, SLOT(trigger()));
×
154
        }
155
        else {
156
                setAcceptedMouseButtons(Qt::LeftButton);
×
157
        }
158
}
×
159

160
StelButton::StelButton(QGraphicsItem* parent,
×
161
                                           const QPixmap& pixOn,
162
                                           const QPixmap& pixOff,
163
                                           const QPixmap& pixHover,
164
                                           StelAction *action,
165
                                           bool noBackground,
166
                                           StelAction *otherAction)
×
167
        : QGraphicsPixmapItem(pixOff, parent)
×
168
{
169
        initCtor(pixOn, pixOff, QPixmap(), pixHover, action, otherAction, noBackground, false);
×
170
}
×
171

172
StelButton::StelButton(QGraphicsItem* parent,
×
173
                                           const QPixmap& pixOn,
174
                                           const QPixmap& pixOff,
175
                                           const QPixmap& pixNoChange,
176
                                           const QPixmap& pixHover,
177
                                           const QString& actionId,
178
                                           bool noBackground,
179
                                           bool isTristate)
×
180
        : QGraphicsPixmapItem(pixOff, parent)
×
181
{
182
        StelAction *action = StelApp::getInstance().getStelActionManager()->findAction(actionId);
×
183
        initCtor(pixOn, pixOff, pixNoChange, pixHover, action, nullptr, noBackground, isTristate);
×
184
}
×
185

186
StelButton::StelButton(QGraphicsItem* parent,
×
187
                                           const QPixmap& pixOn,
188
                                           const QPixmap& pixOff,
189
                                           const QPixmap& pixHover,
190
                                           const QString& actionId,
191
                                           bool noBackground,
192
                                           const QString &otherActionId)
×
193
        : QGraphicsPixmapItem(pixOff, parent)
×
194
{
195
        StelAction *action = StelApp::getInstance().getStelActionManager()->findAction(actionId);
×
196
        StelAction *otherAction=nullptr;
×
197
        if (otherActionId.length()>0)
×
198
                otherAction = StelApp::getInstance().getStelActionManager()->findAction(otherActionId);
×
199

200
        initCtor(pixOn, pixOff, QPixmap(), pixHover, action, otherAction, noBackground, false);
×
201
}
×
202

203

204
int StelButton::toggleChecked(int checked)
×
205
{
206
        if (!isTristate_)
×
207
                checked = !!!checked;
×
208
        else
209
        {
210
                if (++checked > ButtonStateNoChange)
×
211
                        checked = ButtonStateOff;
×
212
        }
213
        return checked;
×
214
}
215

216
void StelButton::hoverEnterEvent(QGraphicsSceneHoverEvent*)
×
217
{
218
        timeLine->setDirection(QTimeLine::Forward);
×
219
        if (timeLine->state()!=QTimeLine::Running)
×
220
                timeLine->start();
×
221

222
        emit hoverChanged(true);
×
223
}
×
224

225
void StelButton::hoverLeaveEvent(QGraphicsSceneHoverEvent*)
×
226
{
227
        timeLine->setDirection(QTimeLine::Backward);
×
228
        if (timeLine->state()!=QTimeLine::Running)
×
229
                timeLine->start();
×
230
        emit hoverChanged(false);
×
231
}
×
232

233
void StelButton::mousePressEvent(QGraphicsSceneMouseEvent* event)
×
234
{
235
        if (event->button()==Qt::LeftButton)
×
236
        {
237
                QGraphicsItem::mousePressEvent(event);
×
238
                event->accept();
×
239
                setChecked(toggleChecked(checked));
×
240
                if (!triggerOnRelease)
×
241
                {
242
                        emit toggled(checked);
×
243
                        emit triggered();
×
244
                }
245
        }
246
        else if  (event->button()==Qt::RightButton)
×
247
        {
248
                QGraphicsItem::mousePressEvent(event);
×
249
                event->accept();
×
250
                //setChecked(toggleChecked(checked));
251
                if (!triggerOnRelease)
×
252
                {
253
                        //emit toggled(checked);
254
                        emit triggeredRight();
×
255
                }
256
        }
257
}
×
258

259
void StelButton::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
×
260
{
261
        if (event->button()==Qt::LeftButton)
×
262
        {
263
                if (action!=nullptr && !action->isCheckable())
×
264
                        setChecked(toggleChecked(checked));
×
265

266
                if (flagChangeFocus) // true if button is on bottom bar
×
267
                        StelMainView::getInstance().focusSky(); // Change the focus after clicking on button
×
268
                if (triggerOnRelease)
×
269
                {
270
                        emit toggled(checked);
×
271
                        emit triggered();
×
272
                }
273
        }
274
        else if  (event->button()==Qt::RightButton)
×
275
        {
276
                //if (flagChangeFocus) // true if button is on bottom bar
277
                //        StelMainView::getInstance().focusSky(); // Change the focus after clicking on button
278
                if (triggerOnRelease)
×
279
                {
280
                        //emit toggled(checked);
281
                        emit triggeredRight();
×
282
                }
283
        }
284
}
×
285

286
void StelButton::updateIcon()
×
287
{
288
        if (opacity < 0.)
×
289
                opacity = 0;
×
290
        QPixmap pix(pixOn.size());
×
291
        pix.setDevicePixelRatio(pixmapsScale);
×
292
        pix.fill(QColor(0,0,0,0));
×
293
        QPainter painter(&pix);
×
294
        painter.setOpacity(opacity);
×
295
        if (!pixBackground.isNull() && noBckground==false && StelApp::getInstance().getStelPropertyManager()->getStelPropertyValue("StelGui.flagUseButtonsBackground").toBool())
×
296
                painter.drawPixmap(0, 0, pixBackground);
×
297

298
        painter.drawPixmap(0, 0,
×
299
                (isTristate_ && checked == ButtonStateNoChange) ? (pixNoChange) :
×
300
                (checked == ButtonStateOn) ? (pixOn) :
×
301
                /* (checked == ButtonStateOff) ? */ (pixOff));
302

303
        if (hoverOpacity > 0)
×
304
        {
305
                painter.setOpacity(hoverOpacity * opacity);
×
306
                painter.drawPixmap(0, 0, pixHover);
×
307
        }
308
        setPixmap(pix);
×
309
        scaledCurrentPixmap = {};
×
310
}
×
311

312
void StelButton::animValueChanged(qreal value)
×
313
{
314
        hoverOpacity = value;
×
315
        updateIcon();
×
316
}
×
317

318
void StelButton::setChecked(int b)
×
319
{
320
        checked=b;
×
321
        updateIcon();
×
322
}
×
323

324
void StelButton::setBackgroundPixmap(const QPixmap &newBackground)
×
325
{
326
        pixBackground = newBackground;
×
327
        updateIcon();
×
328
}
×
329

330
QRectF StelButton::boundingRect() const
×
331
{
332
        return QRectF(0,0, getButtonPixmapWidth(), getButtonPixmapHeight());
×
333
}
334

335
void StelButton::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
×
336
{
337
        /* QPixmap::scaled has much better quality than that scaling via QPainter::drawPixmap, so let's
338
         * have our scaled copy of the pixmap.
339
         * NOTE: we cache this copy for two reasons:
340
         * 1. Performance
341
         * 2. Work around a Qt problem (I think it's a bug): when rendering multiple StelButton items
342
         *    in sequence, only the first one gets the necessary texture parameters set, particularly
343
         *    GL_TEXTURE_MIN_FILTER. On deletion of QPixmap the texture is deleted, and its Id gets
344
         *    assigned to the next QPixmap. Apparently, the Id gets cached somewhere in Qt internals, and
345
         *    becomes similar to a dangling pointer, informing Qt as if the necessary setup has already
346
         *    been done. The result is that after the first button all others in the same panel are black
347
         *    rectangles.
348
         *    Our keeping QPixmap alive instead of deleting it on return from this function prevents this.
349
         */
350
        const double ratio = QOpenGLContext::currentContext()->screen()->devicePixelRatio();
×
351
        if(scaledCurrentPixmap.isNull() || ratio != scaledCurrentPixmap.devicePixelRatioF())
×
352
        {
353
                const auto scale = ratio / pixmapsScale;
×
354
                scaledCurrentPixmap = pixmap().scaled(pixOn.size()*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
×
355
                scaledCurrentPixmap.setDevicePixelRatio(ratio);
×
356
        }
357
        // Align the pixmap to pixel grid, otherwise we'll get artifacts at some scaling factors.
358
        const auto transform = painter->combinedTransform();
×
359
        const auto shift = QPointF(-std::fmod(transform.dx(), 1.),
×
360
                                                           -std::fmod(transform.dy(), 1.));
×
361
        painter->drawPixmap(shift/ratio, scaledCurrentPixmap);
×
362
}
×
363

364
LeftStelBar::LeftStelBar(QGraphicsItem* parent)
×
365
        : QGraphicsItem(parent)
366
        , hideTimeLine(nullptr)
×
367
        , helpLabelPixmap(nullptr)
×
368
{
369
        // Create the help label
370
        helpLabel = new QGraphicsSimpleTextItem("", this);
×
371
        helpLabel->setBrush(QBrush(QColor::fromRgbF(1,1,1,1)));
×
372
        if (qApp->property("text_texture")==true) // CLI option -t given?
×
373
                helpLabelPixmap=new QGraphicsPixmapItem(this);
×
374

375
        setFontSizeFromApp(StelApp::getInstance().getScreenFontSize());
×
376
        connect(&StelApp::getInstance(), SIGNAL(screenFontSizeChanged(int)), this, SLOT(setFontSizeFromApp(int)));
×
377
        connect(&StelApp::getInstance(), SIGNAL(fontChanged(QFont)), this, SLOT(setFont(QFont)));
×
378
}
×
379

380
LeftStelBar::~LeftStelBar()
×
381
{
382
        if (helpLabelPixmap) { delete helpLabelPixmap; helpLabelPixmap=nullptr; }
×
383
}
×
384

385
void LeftStelBar::addButton(StelButton* button)
×
386
{
387
        double posY = 0;
×
388
        if (QGraphicsItem::childItems().size()!=0)
×
389
        {
390
                const QRectF& r = childrenBoundingRect();
×
391
                posY += r.bottom()-1;
×
392
        }
393
        button->setParentItem(this);
×
394
        button->setFocusOnSky(false);
×
395
        button->prepareGeometryChange(); // could possibly be removed when qt 4.6 become stable
×
396
        button->setPos(0., qRound(posY+10.5));
×
397

398
        connect(button, SIGNAL(hoverChanged(bool)), this, SLOT(buttonHoverChanged(bool)));
×
399
}
×
400

401
void LeftStelBar::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
×
402
{
403
}
×
404

405
QRectF LeftStelBar::boundingRect() const
×
406
{
407
        return childrenBoundingRect();
×
408
}
409

410
QRectF LeftStelBar::boundingRectNoHelpLabel() const
×
411
{
412
        // Re-use original Qt code, just remove the help label
413
        QRectF childRect;
×
414
        for (auto* child : QGraphicsItem::childItems())
×
415
        {
416
                if ((child==helpLabel) || (child==helpLabelPixmap))
×
417
                        continue;
×
418
                QPointF childPos = child->pos();
×
419
                QTransform matrix = child->transform() * QTransform().translate(childPos.x(), childPos.y());
×
420
                childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect());
×
421
        }
×
422
        return childRect;
×
423
}
424

425

426
// Update the help label when a button is hovered
427
void LeftStelBar::buttonHoverChanged(bool b)
×
428
{
429
        StelButton* button = qobject_cast<StelButton*>(sender());
×
430
        Q_ASSERT(button);
×
431
        if (b==true)
×
432
        {
433
                if (button->action)
×
434
                {
435
                        QString tip(button->action->getText());
×
436
                        QString shortcut(button->action->getShortcut().toString(QKeySequence::NativeText));
×
437
                        if (!shortcut.isEmpty())
×
438
                        {
439
                                //XXX: this should be unnecessary since we used NativeText.
440
                                if (shortcut == "Space")
×
441
                                        shortcut = q_("Space");
×
442
                                tip += "  [" + shortcut + "]";
×
443
                        }
444
                        helpLabel->setText(tip);
×
445
                        helpLabel->setPos(qRound(boundingRectNoHelpLabel().width()+15.5),qRound(button->pos().y()+button->getButtonPixmapHeight()/2-8));
×
446
                        if (qApp->property("text_texture")==true)
×
447
                        {
448
                                helpLabel->setVisible(false);
×
449
                                helpLabelPixmap->setPixmap(getTextPixmap(tip, helpLabel->font()));
×
450
                                helpLabelPixmap->setPos(helpLabel->pos());
×
451
                                helpLabelPixmap->setVisible(true);
×
452
                        }
453
                }
×
454
        }
455
        else
456
        {
457
                helpLabel->setText("");
×
458
                if (qApp->property("text_texture")==true)
×
459
                        helpLabelPixmap->setVisible(false);
×
460
        }
461
        // Update the screen as soon as possible.
462
        StelMainView::getInstance().thereWasAnEvent();
×
463
}
×
464

465
// Set the pen for all the sub elements
466
void LeftStelBar::setColor(const QColor& c)
×
467
{
468
        helpLabel->setBrush(c);
×
469
}
×
470

471
//! connect from StelApp to resize fonts on the fly.
472
void LeftStelBar::setFontSizeFromApp(int size)
×
473
{
474
        // Font size was developed based on base font size 13, i.e. 12
475
        int screenFontSize = size-1;
×
476
        QFont font=QGuiApplication::font();
×
477
        font.setPixelSize(screenFontSize);
×
478
        helpLabel->setFont(font);
×
479
        StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
480
        if (gui)
×
481
        {
482
                // to avoid crash
483
                SkyGui* skyGui=gui->getSkyGui();
×
484
                if (skyGui)
×
485
                        skyGui->updateBarsPos();
×
486
        }
487
}
×
488

489
//! connect from StelApp to resize fonts on the fly.
490
void LeftStelBar::setFont(QFont font)
×
491
{
492
        font.setPixelSize(StelApp::getInstance().getScreenFontSize()-1);
×
493
        helpLabel->setFont(font);
×
494
        StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
495
        if (gui)
×
496
        {
497
                // to avoid crash
498
                SkyGui* skyGui=gui->getSkyGui();
×
499
                if (skyGui)
×
500
                        skyGui->updateBarsPos();
×
501
        }
502
}
×
503

504

505
BottomStelBar::BottomStelBar(QGraphicsItem* parent,
×
506
                             const QPixmap& pixLeft,
507
                             const QPixmap& pixRight,
508
                             const QPixmap& pixMiddle,
509
                             const QPixmap& pixSingle) :
×
510
        QGraphicsItem(parent),
511
        locationPixmap(nullptr),
×
512
        datetimePixmap(nullptr),
×
513
        fovPixmap(nullptr),
×
514
        fpsPixmap(nullptr),
×
515
        gap(2),
×
516
        pixBackgroundLeft(pixLeft),
×
517
        pixBackgroundRight(pixRight),
×
518
        pixBackgroundMiddle(pixMiddle),
×
519
        pixBackgroundSingle(pixSingle),
×
520
        helpLabelPixmap(nullptr)
×
521
{
522
        // The text is dummy just for testing
523
        datetime = new QGraphicsSimpleTextItem("2008-02-06  17:33", this);
×
524
        location = new QGraphicsSimpleTextItem("Munich, Earth, 500m", this);
×
525
        fov = new QGraphicsSimpleTextItem("FOV 43.45", this);
×
526
        fps = new QGraphicsSimpleTextItem("43.2 FPS", this);
×
527
        if (qApp->property("text_texture")==true) // CLI option -t given?
×
528
        {
529
                datetimePixmap=new QGraphicsPixmapItem(this);
×
530
                locationPixmap=new QGraphicsPixmapItem(this);
×
531
                fovPixmap=new QGraphicsPixmapItem(this);
×
532
                fpsPixmap=new QGraphicsPixmapItem(this);
×
533
                helpLabelPixmap=new QGraphicsPixmapItem(this);
×
534
        }
535

536
        // Create the help label
537
        helpLabel = new QGraphicsSimpleTextItem("", this);
×
538
        helpLabel->setBrush(QBrush(QColor::fromRgbF(1,1,1,1)));
×
539

540
        setColor(QColor::fromRgbF(1,1,1,1));
×
541

542
        setFontSizeFromApp(StelApp::getInstance().getScreenFontSize());
×
543
        connect(&StelApp::getInstance(), &StelApp::screenFontSizeChanged, this, [=](int fontsize){setFontSizeFromApp(fontsize); setFontSizeFromApp(fontsize);}); // We must call that twice to force all geom. updates
×
544
        connect(&StelApp::getInstance(), SIGNAL(fontChanged(QFont)), this, SLOT(setFont(QFont)));
×
545
        connect(StelApp::getInstance().getCore(), &StelCore::flagUseTopocentricCoordinatesChanged, this, [=](bool){updateText(false, true);});
×
546

547
        QSettings* confSettings = StelApp::getInstance().getSettings();
×
548
        setFlagShowTime(confSettings->value("gui/flag_show_datetime", true).toBool());
×
549
        setFlagShowLocation(confSettings->value("gui/flag_show_location", true).toBool());
×
550
        setFlagShowFov(confSettings->value("gui/flag_show_fov", true).toBool());
×
551
        setFlagShowFps(confSettings->value("gui/flag_show_fps", true).toBool());
×
552
        setFlagTimeJd(confSettings->value("gui/flag_time_jd", false).toBool());
×
553
        setFlagFovDms(confSettings->value("gui/flag_fov_dms", false).toBool());
×
554
        setFlagShowTz(confSettings->value("gui/flag_show_tz", true).toBool());
×
555
}
×
556

557
//! connect from StelApp to resize fonts on the fly.
558
void BottomStelBar::setFontSizeFromApp(int size)
×
559
{
560
        QFont font=QGuiApplication::font();
×
561
        // Font size was developed based on base font size 13, i.e. 12
562
        font.setPixelSize(size-1);
×
563
        datetime->setFont(font);
×
564
        location->setFont(font);
×
565
        fov->setFont(font);
×
566
        fps->setFont(font);
×
567
        helpLabel->setFont(font);
×
568
        StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
569
        if (gui)
×
570
        {
571
                // to avoid crash
572
                SkyGui* skyGui=gui->getSkyGui();
×
573
                if (skyGui)
×
574
                {
575
                        skyGui->updateBarsPos();
×
576
                        updateButtonsGroups(); // Make sure bounding boxes are readjusted.
×
577
                }
578
        }
579
        if (qApp->property("text_texture")==true) // CLI option -t given?
×
580
        {
581
                // We must do something to rebuild the pixmaps if fontsize changes. We solve this with setting custom data item 0 to true
582
                datetimePixmap->setData(0, true);
×
583
                locationPixmap->setData(0, true);
×
584
                fovPixmap->setData(0, true);
×
585
                fpsPixmap->setData(0, true);
×
586
                helpLabelPixmap->setData(0, true);
×
587
        }
588
}
×
589

590
//! connect from StelApp to resize fonts on the fly.
591
void BottomStelBar::setFont(QFont font)
×
592
{
593
        font.setPixelSize(StelApp::getInstance().getScreenFontSize()-1);
×
594
        datetime->setFont(font);
×
595
        location->setFont(font);
×
596
        fov->setFont(font);
×
597
        fps->setFont(font);
×
598
        StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
599
        if (gui)
×
600
        {
601
                // to avoid crash
602
                SkyGui* skyGui=gui->getSkyGui();
×
603
                if (skyGui)
×
604
                        skyGui->updateBarsPos();
×
605
        }
606
}
×
607

608
BottomStelBar::~BottomStelBar()
×
609
{
610
        // Remove currently hidden buttons which are not deleted by a parent element
611
        for (auto& group : buttonGroups)
×
612
        {
613
                for (auto* b : qAsConst(group.elems))
×
614
                {
615
                        if (b->parentItem()==nullptr)
×
616
                        {
617
                                delete b;
×
618
                                b=nullptr;
×
619
                        }
620
                }
621
        }
622
        if (datetimePixmap) { delete datetimePixmap; datetimePixmap=nullptr; }
×
623
        if (locationPixmap) { delete locationPixmap; locationPixmap=nullptr; }
×
624
        if (fovPixmap) { delete fovPixmap; fovPixmap=nullptr; }
×
625
        if (fpsPixmap) { delete fpsPixmap; fpsPixmap=nullptr; }
×
626
        if (helpLabelPixmap) { delete helpLabelPixmap; helpLabelPixmap=nullptr; }
×
627
}
×
628

629
void BottomStelBar::addButton(StelButton* button, const QString& groupName, const QString& beforeActionName)
×
630
{
631
        QList<StelButton*>& g = buttonGroups[groupName].elems;
×
632
        bool done = false;
×
633
        for (int i=0; i<g.size(); ++i)
×
634
        {
635
                if (g[i]->action && g[i]->action->objectName()==beforeActionName)
×
636
                {
637
                        g.insert(i, button);
×
638
                        done = true;
×
639
                        break;
×
640
                }
641
        }
642
        if (done == false)
×
643
                g.append(button);
×
644

645
        button->setVisible(true);
×
646
        button->setParentItem(this);
×
647
        button->setFocusOnSky(true);
×
648
        updateButtonsGroups();
×
649

650
        connect(button, SIGNAL(hoverChanged(bool)), this, SLOT(buttonHoverChanged(bool)));
×
651
        emit sizeChanged();
×
652
}
×
653

654
StelButton* BottomStelBar::hideButton(const QString& actionName)
×
655
{
656
        QString gName;
×
657
        StelButton* bToRemove = nullptr;
×
658
        for (auto iter = buttonGroups.begin(); iter != buttonGroups.end(); ++iter)
×
659
        {
660
                int i=0;
×
661
                for (auto* b : qAsConst(iter.value().elems))
×
662
                {
663
                        if (b->action && b->action->objectName()==actionName)
×
664
                        {
665
                                gName = iter.key();
×
666
                                bToRemove = b;
×
667
                                iter.value().elems.removeAt(i);
×
668
                                break;
×
669
                        }
670
                        ++i;
×
671
                }
672
        }
673
        if (bToRemove == nullptr)
×
674
                return nullptr;
×
675
        if (buttonGroups[gName].elems.size() == 0)
×
676
        {
677
                buttonGroups.remove(gName);
×
678
        }
679
        // Cannot really delete because some part of the GUI depend on the presence of some buttons
680
        // so just make invisible
681
        bToRemove->setParentItem(nullptr);
×
682
        bToRemove->setVisible(false);
×
683
        updateButtonsGroups();
×
684
        emit sizeChanged();
×
685
        return bToRemove;
×
686
}
×
687

688
// Set the margin at the left and right of a button group in pixels
689
void BottomStelBar::setGroupMargin(const QString& groupName, int left, int right)
×
690
{
691
        if (!buttonGroups.contains(groupName))
×
692
                return;
×
693
        buttonGroups[groupName].leftMargin = left;
×
694
        buttonGroups[groupName].rightMargin = right;
×
695
        updateButtonsGroups();
×
696
}
697

698
//! Change the background of a group
699
void BottomStelBar::setGroupBackground(const QString& groupName,
×
700
                                       const QPixmap& pixLeft,
701
                                       const QPixmap& pixRight,
702
                                       const QPixmap& pixMiddle,
703
                                       const QPixmap& pixSingle)
704
{
705
        if (!buttonGroups.contains(groupName))
×
706
                return;
×
707

708
        buttonGroups[groupName].pixBackgroundLeft = new QPixmap(pixLeft);
×
709
        buttonGroups[groupName].pixBackgroundRight = new QPixmap(pixRight);
×
710
        buttonGroups[groupName].pixBackgroundMiddle = new QPixmap(pixMiddle);
×
711
        buttonGroups[groupName].pixBackgroundSingle = new QPixmap(pixSingle);
×
712
        updateButtonsGroups();
×
713
}
714

715
QRectF BottomStelBar::getButtonsBoundingRect() const
×
716
{
717
        QRectF childRect;
×
718
        bool hasBtn = false;
×
719
        if (qApp->property("text_texture")==true) // CLI option -t given?
×
720
        {
721
                // For unknown reasons the matrix operation is not needed and even wrong here.
722
                for (auto* child : QGraphicsItem::childItems())
×
723
                {
724
                        if (qgraphicsitem_cast<StelButton*>(child)==nullptr)
×
725
                                continue;
×
726
                        hasBtn = true;
×
727
                        childRect |= child->boundingRect();
×
728
                }
×
729
        }
730
        else
731
        {
732
                for (auto* child : QGraphicsItem::childItems())
×
733
                {
734
                        if (qgraphicsitem_cast<StelButton*>(child)==nullptr)
×
735
                                continue;
×
736
                        hasBtn = true;
×
737
                        QPointF childPos = child->pos();
×
738
                        //qDebug() << "childPos" << childPos;
739
                        QTransform matrix = child->transform() * QTransform().translate(childPos.x(), childPos.y());
×
740
                        childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect());
×
741
                }
×
742
        }
743

744
        if (hasBtn)
×
745
                return QRectF(0, 0, childRect.width(), childRect.height());
×
746
        else
747
                return QRectF();
×
748
}
749

750
void BottomStelBar::updateButtonsGroups()
×
751
{
752
        double x = 0;
×
753
        QFontMetrics statusFM(datetime->font());
×
754
        const double y = statusFM.lineSpacing()+gap; // Take natural font geometry into account
×
755
        for (auto& group : buttonGroups)
×
756
        {
757
                QList<StelButton*>& buttons = group.elems;
×
758
                if (buttons.empty())
×
759
                        continue;
×
760
                x += group.leftMargin;
×
761
                int n = 0;
×
762
                for (auto* b : buttons)
×
763
                {
764
                        // We check if the group has its own background if not the case
765
                        // We apply a default background.
766
                        if (n == 0)
×
767
                        {
768
                                if (buttons.size() == 1)
×
769
                                {
770
                                        if (group.pixBackgroundSingle == nullptr)
×
771
                                                b->setBackgroundPixmap(pixBackgroundSingle);
×
772
                                        else
773
                                                b->setBackgroundPixmap(*group.pixBackgroundSingle);
×
774
                                }
775
                                else
776
                                {
777
                                        if (group.pixBackgroundLeft == nullptr)
×
778
                                                b->setBackgroundPixmap(pixBackgroundLeft);
×
779
                                        else
780
                                                b->setBackgroundPixmap(*group.pixBackgroundLeft);
×
781
                                }
782
                        }
783
                        else if (n == buttons.size()-1)
×
784
                        {
785
                                if (buttons.size() != 1)
×
786
                                {
787
                                        if (group.pixBackgroundSingle == nullptr)
×
788
                                                b->setBackgroundPixmap(pixBackgroundSingle);
×
789
                                        else
790
                                                b->setBackgroundPixmap(*group.pixBackgroundSingle);
×
791
                                }
792
                                if (group.pixBackgroundRight == nullptr)
×
793
                                        b->setBackgroundPixmap(pixBackgroundRight);
×
794
                                else
795
                                        b->setBackgroundPixmap(*group.pixBackgroundRight);
×
796
                        }
797
                        else
798
                        {
799
                                if (group.pixBackgroundMiddle == nullptr)
×
800
                                        b->setBackgroundPixmap(pixBackgroundMiddle);
×
801
                                else
802
                                        b->setBackgroundPixmap(*group.pixBackgroundMiddle);
×
803
                        }
804
                        // Update the button pixmap
805
                        b->animValueChanged(0.);
×
806
                        b->setPos(x, y);
×
807
                        x += b->getButtonPixmapWidth();
×
808
                        ++n;
×
809
                }
810
                x+=group.rightMargin;
×
811
        }
812
        updateText(true);
×
813
}
×
814

815
// create text elements and tooltips in bottom toolbar.
816
// Make sure to avoid any change if not necessary to avoid triggering useless redraw
817
// This is also called when button groups have been updated.
818
void BottomStelBar::updateText(bool updatePos, bool updateTopocentric)
×
819
{
820
        StelCore* core = StelApp::getInstance().getCore();
×
821
        const double jd = core->getJD();
×
822
        const double deltaT = core->getDeltaT();
×
823
        const double sigma = StelUtils::getDeltaTStandardError(jd);
×
824
        QString validRangeMarker = "";
×
825
        core->getCurrentDeltaTAlgorithmValidRangeDescription(jd, &validRangeMarker);
×
826

827
        const StelLocaleMgr& locmgr = StelApp::getInstance().getLocaleMgr();
×
828
        QString tz = locmgr.getPrintableTimeZoneLocal(jd);
×
829
        QString newDateInfo = " ";
×
830
        if (getFlagShowTime())
×
831
        {
832
                if (getFlagShowTz())
×
833
                        newDateInfo = QString("%1 %2 %3").arg(locmgr.getPrintableDateLocal(jd), locmgr.getPrintableTimeLocal(jd), tz);
×
834
                else
835
                        newDateInfo = QString("%1 %2").arg(locmgr.getPrintableDateLocal(jd), locmgr.getPrintableTimeLocal(jd));
×
836
        }
837
        QString newDateAppx = QString("JD %1").arg(jd, 0, 'f', 5); // up to seconds
×
838
        if (getFlagTimeJd())
×
839
        {
840
                newDateAppx = newDateInfo;
×
841
                newDateInfo = QString("JD %1").arg(jd, 0, 'f', 5); // up to seconds
×
842
        }
843

844
        QString planetName = core->getCurrentLocation().planetName;
×
845
        QString planetNameI18n;
×
846
        if (planetName=="SpaceShip") // Avoid crash
×
847
        {
848
                const StelTranslator& trans = StelApp::getInstance().getLocaleMgr().getSkyTranslator();
×
849
                planetNameI18n = trans.qtranslate(planetName, "special celestial body"); // added context
×
850
        }
851
        else
852
                planetNameI18n = GETSTELMODULE(SolarSystem)->searchByEnglishName(planetName)->getNameI18n();
×
853

854
        QString tzName = core->getCurrentTimeZone();
×
855
        if (tzName.contains("system_default") || (tzName.isEmpty() && planetName=="Earth"))
×
856
                tzName = q_("System default");
×
857

858
        QString currTZ = QString("%1: %2").arg(q_("Time zone"), tzName);
×
859

860
        if (tzName.contains("LMST") || tzName.contains("auto") || (planetName=="Earth" && jd<=StelCore::TZ_ERA_BEGINNING && !core->getUseCustomTimeZone()) )
×
861
                currTZ = q_("Local Mean Solar Time");
×
862

863
        if (tzName.contains("LTST"))
×
864
                currTZ = q_("Local True Solar Time");
×
865

866
        // TRANSLATORS: unit of measurement: minutes per second
867
        QString timeRateMU = qc_("min/s", "unit of measurement");
×
868
        double timeRate = qAbs(core->getTimeRate()/StelCore::JD_SECOND);
×
869
        double timeSpeed = timeRate/60.;
×
870

871
        if (timeSpeed>=60.)
×
872
        {
873
                timeSpeed /= 60.;
×
874
                // TRANSLATORS: unit of measurement: hours per second
875
                timeRateMU = qc_("hr/s", "unit of measurement");
×
876
        }
877
        if (timeSpeed>=24.)
×
878
        {
879
                timeSpeed /= 24.;
×
880
                // TRANSLATORS: unit of measurement: days per second
881
                timeRateMU = qc_("d/s", "unit of measurement");
×
882
        }
883
        if (timeSpeed>=365.25)
×
884
        {
885
                timeSpeed /= 365.25;
×
886
                // TRANSLATORS: unit of measurement: years per second
887
                timeRateMU = qc_("yr/s", "unit of measurement");
×
888
        }
889
        QString timeRateInfo = QString("%1: x%2").arg(q_("Simulation speed"), QString::number(timeRate, 'f', 0));
×
890
        if (timeRate>60.)
×
891
                timeRateInfo = QString("%1: x%2 (%3 %4)").arg(q_("Simulation speed"), QString::number(timeRate, 'f', 0), QString::number(timeSpeed, 'f', 2), timeRateMU);
×
892

893
        if (datetime->text()!=newDateInfo || (datetimePixmap && datetimePixmap->data(0).toBool()))
×
894
        {
895
                updatePos = true;
×
896
                datetime->setText(newDateInfo);
×
897
        }
898

899
        if (core->getCurrentDeltaTAlgorithm()!=StelCore::WithoutCorrection)
×
900
        {
901
                QString sigmaInfo("");
×
902
                if (sigma>0)
×
903
                        sigmaInfo = QString("; %1(%2T) = %3s").arg(QChar(0x03c3)).arg(QChar(0x0394)).arg(sigma, 3, 'f', 1);
×
904

905
                QString deltaTInfo;
×
906
                if (qAbs(deltaT)>60.)
×
907
                        deltaTInfo = QString("%1 (%2s)%3").arg(StelUtils::hoursToHmsStr(deltaT/3600.)).arg(deltaT, 5, 'f', 2).arg(validRangeMarker);
×
908
                else
909
                        deltaTInfo = QString("%1s%2").arg(deltaT, 3, 'f', 3).arg(validRangeMarker);
×
910

911
                // the corrective ndot to be displayed could be set according to the currently used DeltaT algorithm.
912
                //float ndot=core->getDeltaTnDot();
913
                // or just to the used ephemeris. This has to be read as "Selected DeltaT formula used, but with the ephemeris's nDot applied it corrects DeltaT to..."
914
                const double ndot=( (EphemWrapper::use_de430(jd) || EphemWrapper::use_de431(jd) || EphemWrapper::use_de440(jd) || EphemWrapper::use_de441(jd)) ? -25.8 : -23.8946 );
×
915

916
                datetime->setToolTip(QString("<p style='white-space:pre'>%1T = %2 [n%8 @ %3\"/cy%4%5]<br>%6<br>%7<br>%9</p>").arg(QChar(0x0394), deltaTInfo, QString::number(ndot, 'f', 4), QChar(0x00B2), sigmaInfo, newDateAppx, currTZ, QChar(0x2032), timeRateInfo));
×
917
        }
×
918
        else
919
                datetime->setToolTip(QString("<p style='white-space:pre'>%1<br>%2<br>%3</p>").arg(newDateAppx, currTZ, timeRateInfo));
×
920

921
        if (qApp->property("text_texture")==true) // CLI option -t given?
×
922
        {
923
                datetime->setVisible(false); // hide normal thingy.
×
924
                datetimePixmap->setPixmap(getTextPixmap(newDateInfo, datetime->font()));
×
925
                datetimePixmap->setData(0, false);
×
926
        }
927

928
        // build location tooltip
929
        QString newLocation("");
×
930
        if (getFlagShowLocation())
×
931
        {
932
                const StelLocation* loc = &core->getCurrentLocation();
×
933
                if (core->getCurrentPlanet()->getPlanetType()==Planet::isObserver)
×
934
                        newLocation = planetNameI18n;
×
935
                else if(loc->name.isEmpty())
×
936
                        newLocation = planetNameI18n +", "+StelUtils::decDegToDmsStr(loc->getLatitude())+", "+StelUtils::decDegToDmsStr(loc->getLongitude());
×
937
                else if (loc->name.contains("->")) // a spaceship
×
938
                        newLocation = QString("%1 [%2 %3]").arg(planetNameI18n, q_("flight"), loc->name);
×
939
                else
940
                        //TRANSLATORS: Unit of measure for distance - meter
941
                        newLocation = planetNameI18n +", "+q_(loc->name) + ", "+ QString("%1 %2").arg(loc->altitude).arg(qc_("m", "distance"));
×
942
        }
943
        // When topocentric switch is toggled, this must be redrawn!
944
        if (location->text()!=newLocation || updateTopocentric || (locationPixmap && locationPixmap->data(0).toBool()))
×
945
        {
946
                updatePos = true;
×
947
                location->setText(newLocation);
×
948
                double lat = static_cast<double>(core->getCurrentLocation().getLatitude());
×
949
                double lon = static_cast<double>(core->getCurrentLocation().getLongitude());
×
950
                QString latStr, lonStr, pm;
×
951
                if (lat >= 0)
×
952
                        pm = "N";
×
953
                else
954
                {
955
                        pm = "S";
×
956
                        lat *= -1;
×
957
                }
958
                latStr = QString("%1%2%3").arg(pm).arg(lat).arg(QChar(0x00B0));
×
959
                if (lon >= 0)
×
960
                        pm = "E";
×
961
                else
962
                {
963
                        pm = "W";
×
964
                        lon *= -1;
×
965
                }
966
                lonStr = QString("%1%2%3").arg(pm).arg(lon).arg(QChar(0x00B0));
×
967
                QString rho, weather;
×
968
                if (core->getUseTopocentricCoordinates())
×
969
                        rho = QString("%1 %2 %3").arg(q_("planetocentric distance")).arg(core->getCurrentObserver()->getDistanceFromCenter() * AU).arg(qc_("km", "distance"));
×
970
                else
971
                        rho = q_("planetocentric observer");
×
972

973
                if (newLocation.contains("->")) // a spaceship
×
974
                        location->setToolTip(QString());
×
975
                else
976
                {
977
                        if (core->getCurrentPlanet()->hasAtmosphere())
×
978
                        {
979
                                const StelPropertyMgr* propMgr=StelApp::getInstance().getStelPropertyManager();
×
980
                                weather = QString("%1: %2 %3; %4: %5 °C").arg(q_("Atmospheric pressure"), QString::number(propMgr->getStelPropertyValue("StelSkyDrawer.atmospherePressure").toDouble(), 'f', 2), qc_("mbar", "pressure unit"), q_("temperature"), QString::number(propMgr->getStelPropertyValue("StelSkyDrawer.atmosphereTemperature").toDouble(), 'f', 1));
×
981
                                location->setToolTip(QString("<p style='white-space:pre'>%1 %2; %3<br>%4</p>").arg(latStr, lonStr, rho, weather));
×
982
                        }
983
                        else if (core->getCurrentPlanet()->getPlanetType()==Planet::isObserver)
×
984
                                newLocation = planetNameI18n;
×
985
                        else
986
                                location->setToolTip(QString("%1 %2; %3").arg(latStr, lonStr, rho));
×
987
                }
988

989
                if (qApp->property("text_texture")==true) // CLI option -t given?
×
990
                {
991
                        locationPixmap->setPixmap(getTextPixmap(newLocation, location->font()));
×
992
                        locationPixmap->setData(0, false);
×
993
                        location->setVisible(false);
×
994
                }
995
        }
×
996

997
        // build fov tooltip
998
        // TRANSLATORS: Field of view. Please use abbreviation.
999
        QString fovdms = StelUtils::decDegToDmsStr(core->getMovementMgr()->getCurrentFov());
×
1000
        QString fovText;
×
1001
        if (getFlagFovDms())
×
1002
                fovText=QString("%1 %2").arg(qc_("FOV", "abbreviation"), fovdms);
×
1003
        else
1004
                fovText=QString("%1 %2%3").arg(qc_("FOV", "abbreviation"), QString::number(core->getMovementMgr()->getCurrentFov(), 'g', 3), QChar(0x00B0));
×
1005

1006
        if (fov->text()!=fovText || (fovPixmap && fovPixmap->data(0).toBool()))
×
1007
        {
1008
                updatePos = true;
×
1009
                if (getFlagShowFov())
×
1010
                {
1011
                        // DEBUG: SHOW DIFFERENT VALUES...
1012
//                        SkyGui * skyGui= static_cast<StelGui *>(StelApp::getInstance().getGui())->getSkyGui();
1013
//                        QFontMetrics locationMetrics(location->font());
1014
//                        QRectF buttonBoundingRect=getButtonsBoundingRect();
1015
//                        QString bbbr=QString("BBX: %1 ww: %2 hh: %3 h: %4,  %5 ch: %6x%7 bb: %8x%9").arg(QString::number(boundingRectNoHelpLabel().height(), 'f', 3),
1016
//                                                                                QString::number(skyGui->getSkyGuiWidth()),
1017
//                                                                                QString::number(skyGui->getSkyGuiHeight()),
1018
//                                                                                QString::number(locationMetrics.boundingRect("M").height()), // h: height
1019
//                                                                                QString::number(childItems().count()),                       // NN ch.
1020
//                                                                                QString::number(childrenBoundingRect().width()),
1021
//                                                                                QString::number(childrenBoundingRect().height()),
1022
//                                                                                QString::number(buttonBoundingRect.width()),
1023
//                                                                                QString::number(buttonBoundingRect.height()));
1024
//                        fov->setText(bbbr);
1025
                        fov->setText(fovText);
×
1026
                        fov->setToolTip(QString("%1: %2").arg(q_("Field of view"), fovdms));
×
1027
                        if (qApp->property("text_texture")==true) // CLI option -t given?
×
1028
                        {
1029
                                fovPixmap->setPixmap(getTextPixmap(fovText, fov->font()));
×
1030
                                fovPixmap->setData(0, false);
×
1031
                                fov->setVisible(false);
×
1032
                        }
1033
                }
1034
                else
1035
                {
1036
                        fov->setText("");
×
1037
                        fov->setToolTip("");
×
1038
                }
1039
        }
1040

1041
        // build fps tooltip
1042
        // TRANSLATORS: Frames per second. Please use abbreviation.
1043
        QString fpsText = QString("%1 %2").arg(QString::number(StelApp::getInstance().getFps(), 'g', 3), qc_("FPS", "abbreviation"));;
×
1044
        if (fps->text()!=fpsText || (fpsPixmap && fpsPixmap->data(0).toBool()))
×
1045
        {
1046
                updatePos = true;
×
1047
                if (getFlagShowFps())
×
1048
                {
1049
                        fps->setText(fpsText);
×
1050
                        fps->setToolTip(q_("Frames per second"));
×
1051
                        if (qApp->property("text_texture")==true) // CLI option -t given?
×
1052
                        {
1053
                                fpsPixmap->setPixmap(getTextPixmap(fpsText, fps->font()));
×
1054
                                fpsPixmap->setData(0, false);
×
1055
                                fps->setVisible(false);
×
1056
                        }
1057
                }
1058
                else
1059
                {
1060
                        fps->setText("");
×
1061
                        fps->setToolTip("");
×
1062
                }
1063
        }
1064

1065
        if (updatePos)
×
1066
        {
1067
                // The location string starts at left, dateTime ends at right. FoV and FPS come ahead of dateTime.
1068
                // In case the strings are wider than available button space, they are now pushed to the right.
1069
                QFontMetrics fontMetrics(location->font());
×
1070
                int fpsShift     = qMax(fontMetrics.boundingRect(fps->text()+"MMM").width(), fontMetrics.boundingRect(qc_("FPS", "abbreviation")+"MM.M MMM").width());
×
1071
                int fovShift     = fontMetrics.boundingRect(fov->text()+"MMM").width() + fpsShift;
×
1072
                int locationWidth= fontMetrics.boundingRect(location->text() + "MMM").width();
×
1073
                location->setPos(0, 0);
×
1074

1075
                QRectF rectCh = getButtonsBoundingRect();
×
1076
                int dateTimePos = static_cast<int>(rectCh.right()-datetime->boundingRect().width())-5;
×
1077
                if ((dateTimePos%2) == 1) dateTimePos--; // make even pixel
×
1078

1079
                const int rightPush=qMax(0, locationWidth-(dateTimePos-fovShift));
×
1080
                datetime->setPos(dateTimePos+rightPush, 0);
×
1081
                fov->setPos(datetime->x()-fovShift, 0);
×
1082
                fps->setPos(datetime->x()-fpsShift, 0);
×
1083
                if (qApp->property("text_texture")==true) // CLI option -t given?
×
1084
                {
1085
                        const qreal yPos = -fontMetrics.descent();
×
1086
                        locationPixmap->setPos(0,yPos);
×
1087
                        int dateTimePos = static_cast<int>(rectCh.right()-datetimePixmap->boundingRect().width())-5;
×
1088
                        if ((dateTimePos%2) == 1) dateTimePos--; // make even pixel
×
1089
                        datetimePixmap->setPos(dateTimePos+rightPush, yPos);
×
1090
                        fovPixmap->setPos(datetimePixmap->x()-fovShift, yPos);
×
1091
                        fpsPixmap->setPos(datetimePixmap->x()-fpsShift, yPos);
×
1092
                }
1093

1094
//                // TEST
1095
//                QRectF br=boundingRect();            // Same size as childrenBoundingRect, just at offset 0/0.
1096
//                QRectF chBR=childrenBoundingRect();  // Same as boundingRectNoHelpLabel unless helpItem is shown.
1097
//                QRectF bbnhl=boundingRectNoHelpLabel();
1098
//                QString brStr=QString("BR: %1x%2+%3+%4 CBR: %5x%6+%7+%8 BBNHL: %9x%10+%11+%12").arg(QString::number(br.width(), 'f', 2),
1099
//                                                                              QString::number(br.height(), 'f', 2),
1100
//                                                                              QString::number(br.left(), 'f', 2),
1101
//                                                                              QString::number(br.top(), 'f', 2),
1102
//                                                                              QString::number(chBR.width(), 'f', 2),
1103
//                                                                              QString::number(chBR.height(), 'f', 2),
1104
//                                                                              QString::number(chBR.left(), 'f', 2),
1105
//                                                                              QString::number(chBR.top(), 'f', 2)
1106
//                                                                              ).arg(
1107
//                                                                              QString::number(bbnhl.width(), 'f', 2),
1108
//                                                                              QString::number(bbnhl.height(), 'f', 2),
1109
//                                                                              QString::number(bbnhl.left(), 'f', 2),
1110
//                                                                              QString::number(bbnhl.top(), 'f', 2)
1111
//                                                                              );
1112
//                datetime->setText(brStr);
1113
                emit sizeChanged();
×
1114
        }
×
1115
}
×
1116

1117
void BottomStelBar::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
×
1118
{
1119
        updateText();
×
1120
}
×
1121

1122
QRectF BottomStelBar::boundingRect() const
×
1123
{
1124
        if (QGraphicsItem::childItems().size()==0)
×
1125
                return QRectF();
×
1126
        const QRectF& r = childrenBoundingRect(); // BBX of status text (Location/FoV/FPS/Time) and buttons
×
1127
        //return QRectF(0, 0, r.width()-1, r.height()-1); // Why return a smaller BR than children?
1128
        return QRectF(0, 0, r.width(), r.height());
×
1129
}
1130

1131
QRectF BottomStelBar::boundingRectNoHelpLabel() const
×
1132
{
1133
        // Re-use original Qt code, just remove the help label
1134
        QRectF childRect;
×
1135
        for (const auto* child : QGraphicsItem::childItems())
×
1136
        {
1137
                if ((child==helpLabel) || (child==helpLabelPixmap))
×
1138
                        continue;
×
1139
                QPointF childPos = child->pos();
×
1140
                QTransform matrix = child->transform() * QTransform().translate(childPos.x(), childPos.y());
×
1141
                childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect());
×
1142
        }
×
1143
        return childRect;
×
1144
}
1145

1146
// Set the brush for all the sub elements
1147
void BottomStelBar::setColor(const QColor& c)
×
1148
{
1149
        datetime->setBrush(c);
×
1150
        location->setBrush(c);
×
1151
        fov->setBrush(c);
×
1152
        fps->setBrush(c);
×
1153
        helpLabel->setBrush(c);
×
1154
}
×
1155

1156
// Update the help label when a button is hovered
1157
void BottomStelBar::buttonHoverChanged(bool b)
×
1158
{
1159
        StelButton* button = qobject_cast<StelButton*>(sender());
×
1160
        Q_ASSERT(button);
×
1161
        if (b==true)
×
1162
        {
1163
                StelAction* action = button->action;
×
1164
                if (action)
×
1165
                {
1166
                        QString tip(action->getText());
×
1167
                        QString shortcut(action->getShortcut().toString(QKeySequence::NativeText));
×
1168
                        if (!shortcut.isEmpty())
×
1169
                        {
1170
                                //XXX: this should be unnecessary since we used NativeText.
1171
                                if (shortcut == "Space")
×
1172
                                        shortcut = q_("Space");
×
1173
                                tip += "  [" + shortcut + "]";
×
1174
                        }
1175
                        helpLabel->setText(tip);
×
1176
                        //helpLabel->setPos(button->pos().x()+button->pixmap().size().width()/2,-27);
1177
                        helpLabel->setPos(20,-10-location->font().pixelSize()); // Set help text XY position. Y adjusted for font size!
×
1178

1179
                        if (qApp->property("text_texture")==true)
×
1180
                        {
1181
                                helpLabel->setVisible(false);
×
1182
                                helpLabelPixmap->setPixmap(getTextPixmap(tip, helpLabel->font()));
×
1183
                                helpLabelPixmap->setPos(helpLabel->pos());
×
1184
                                helpLabelPixmap->setVisible(true);
×
1185
                        }
1186
                }
×
1187
        }
1188
        else
1189
        {
1190
                helpLabel->setText("");
×
1191
                if (qApp->property("text_texture")==true)
×
1192
                        helpLabelPixmap->setVisible(false);
×
1193
        }
1194
        // Update the screen as soon as possible.
1195
        StelMainView::getInstance().thereWasAnEvent();
×
1196
}
×
1197

1198
StelBarsPath::StelBarsPath(QGraphicsItem* parent) : QGraphicsPathItem(parent), roundSize(6)
×
1199
{
1200
        setBrush(QBrush(QColor::fromRgbF(0.22, 0.22, 0.23, 0.2)));
×
1201
        QPen aPen(QColor::fromRgbF(0.7,0.7,0.7,0.5));
×
1202
        // aPen.setWidthF(1.); // 1=default!
1203
        setPen(aPen);
×
1204
}
×
1205

1206
void StelBarsPath::updatePath(BottomStelBar* bottom, LeftStelBar* left)
×
1207
{
1208
        const QPointF l = left->pos() + QPointF(-0.5,0.5);   // pos() is the top-left point in the parent's coordinate system.
×
1209
        const QRectF lB = left->boundingRectNoHelpLabel();
×
1210
        const QPointF b = bottom->pos() + QPointF(-0.5,0.5);
×
1211
        const QRectF bB = bottom->boundingRectNoHelpLabel();
×
1212

1213
        QPainterPath path(QPointF(l.x()-roundSize, l.y()-roundSize));                                 // top left point
×
1214
        //path.lineTo(l.x()+lB.width()-roundSize,l.y()-roundSize);                                    // top edge. Not needed because the arc connects anyhow!
1215
        path.arcTo(l.x()+lB.width()-roundSize, l.y()-roundSize, 2.*roundSize, 2.*roundSize, 90, -90); // top-right curve of left bar
×
1216
        path.lineTo(l.x()+lB.width()+roundSize, b.y()-roundSize);                                     // vertical to inside sharp edge
×
1217
        //path.lineTo(b.x()+bB.width(),b.y()-roundSize);                                              // Top edge of bottom bar. Not needed because the arc connects anyhow!
1218
        path.arcTo(b.x()+bB.width()-roundSize, b.y()-roundSize, 2.*roundSize, 2.*roundSize, 90, -90); // top right curved edge of bottom bar (just connects.)
×
1219
        path.lineTo(b.x()+bB.width()+roundSize, b.y()+bB.height()+roundSize);
×
1220
        path.lineTo(l.x()-roundSize, b.y()+bB.height()+roundSize);                                    // bottom line (outside screen area!)
×
1221
        path.closeSubpath();                                                                          // vertical line up left outside screen
×
1222
        setPath(path);
×
1223
}
×
1224

1225
void StelBarsPath::setBackgroundOpacity(double opacity)
×
1226
{
1227
        setBrush(QBrush(QColor::fromRgbF(0.22, 0.22, 0.23, opacity)));
×
1228
}
×
1229

1230
StelProgressBarMgr::StelProgressBarMgr(QGraphicsItem* parent):
×
1231
        QGraphicsWidget(parent)
×
1232
{
1233
        setLayout(new QGraphicsLinearLayout(Qt::Vertical));
×
1234
}
×
1235
/*
1236
QRectF StelProgressBarMgr::boundingRect() const
1237
{
1238
        if (QGraphicsItem::children().size()==0)
1239
                return QRectF();
1240
        const QRectF& r = childrenBoundingRect();
1241
        return QRectF(0, 0, r.width()-1, r.height()-1);
1242
}*/
1243

1244
void StelProgressBarMgr::addProgressBar(const StelProgressController* p)
×
1245
{
1246
        StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
1247
        QProgressBar* pb = new QProgressBar();
×
1248
        pb->setFixedHeight(25);
×
1249
        pb->setFixedWidth(200);
×
1250
        pb->setTextVisible(true);
×
1251
        pb->setValue(p->getValue());
×
1252
        pb->setMinimum(p->getMin());
×
1253
        pb->setMaximum(p->getMax());
×
1254
        pb->setFormat(p->getFormat());
×
1255
        if (gui!=nullptr)
×
1256
                pb->setStyleSheet(gui->getStelStyle().qtStyleSheet);
×
1257
        QGraphicsProxyWidget* pbProxy = new QGraphicsProxyWidget();
×
1258
        pbProxy->setWidget(pb);
×
1259
        pbProxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
×
1260
        pbProxy->setZValue(150);        
×
1261
        static_cast<QGraphicsLinearLayout*>(layout())->addItem(pbProxy);
×
1262
        allBars.insert(p, pb);
×
1263
        pb->setVisible(true);
×
1264
        
1265
        connect(p, SIGNAL(changed()), this, SLOT(oneBarChanged()));
×
1266
}
×
1267

1268
void StelProgressBarMgr::removeProgressBar(const StelProgressController *p)
×
1269
{
1270
        QProgressBar* pb = allBars[p];
×
1271
        pb->deleteLater();
×
1272
        allBars.remove(p);
×
1273
}
×
1274

1275
void StelProgressBarMgr::oneBarChanged()
×
1276
{
1277
        const StelProgressController *p = static_cast<StelProgressController*>(QObject::sender());
×
1278
        QProgressBar* pb = allBars[p];
×
1279
        pb->setValue(p->getValue());
×
1280
        pb->setMinimum(p->getMin());
×
1281
        pb->setMaximum(p->getMax());
×
1282
        pb->setFormat(p->getFormat());
×
1283
}
×
1284

1285
CornerButtons::CornerButtons(QGraphicsItem* parent) :
×
1286
        QGraphicsItem(parent),
1287
        lastOpacity(10)
×
1288
{
1289
}
×
1290

1291
void CornerButtons::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
×
1292
{
1293
        // Do nothing. Just paint the child widgets
1294
}
×
1295

1296
QRectF CornerButtons::boundingRect() const
×
1297
{
1298
        if (QGraphicsItem::childItems().size()==0)
×
1299
                return QRectF();
×
1300
        const QRectF& r = childrenBoundingRect();
×
1301
        return QRectF(0, 0, r.width()-1, r.height()-1);
×
1302
}
1303

1304
void CornerButtons::setOpacity(double opacity)
×
1305
{
1306
        if (opacity<=0. && lastOpacity<=0.)
×
1307
                return;
×
1308
        lastOpacity = opacity;
×
1309
        if (QGraphicsItem::childItems().size()==0)
×
1310
                return;
×
1311
        for (auto* child : QGraphicsItem::childItems())
×
1312
        {
1313
                StelButton* sb = qgraphicsitem_cast<StelButton*>(child);
×
1314
                Q_ASSERT(sb!=nullptr);
×
1315
                sb->setOpacity(opacity);
×
1316
        }
×
1317
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc