mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-04-20 18:31:31 -06:00
qt: Show emulated notification LED
This commit is contained in:
parent
d29e15f219
commit
3d69741076
@ -174,6 +174,8 @@ add_library(citra_qt STATIC EXCLUDE_FROM_ALL
|
||||
multiplayer/state.cpp
|
||||
multiplayer/state.h
|
||||
multiplayer/validation.h
|
||||
notification_led.cpp
|
||||
notification_led.h
|
||||
precompiled_headers.h
|
||||
qt_image_interface.cpp
|
||||
qt_image_interface.h
|
||||
|
||||
@ -352,6 +352,8 @@ GMainWindow::GMainWindow(Core::System& system_)
|
||||
Camera::RegisterFactory("image", std::make_unique<Camera::StillImageCameraFactory>());
|
||||
Camera::RegisterFactory("qt", std::make_unique<Camera::QtMultimediaCameraFactory>(qt_cameras));
|
||||
|
||||
system.RegisterInfoLEDColorChanged([this]() { emit InfoLEDColorChanged(); });
|
||||
|
||||
LoadTranslation();
|
||||
|
||||
Pica::g_debug_context = Pica::DebugContext::Construct();
|
||||
@ -606,6 +608,20 @@ void GMainWindow::InitializeWidgets() {
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusText());
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon());
|
||||
|
||||
QFrame* sep = new QFrame(this);
|
||||
sep->setFrameShape(QFrame::VLine);
|
||||
sep->setFrameShadow(QFrame::Sunken);
|
||||
sep->setFixedHeight(16);
|
||||
statusBar()->addPermanentWidget(sep);
|
||||
|
||||
notification_led = new LedWidget();
|
||||
notification_led->setToolTip(tr("Emulated notification LED"));
|
||||
statusBar()->addPermanentWidget(notification_led);
|
||||
connect(this, &GMainWindow::InfoLEDColorChanged, this, [this] {
|
||||
auto led_color = system.GetInfoLEDColor();
|
||||
notification_led->setColor(QColor(led_color.r(), led_color.g(), led_color.b()));
|
||||
});
|
||||
|
||||
statusBar()->setVisible(true);
|
||||
|
||||
// Removes an ugly inner border from the status bar widgets under Linux
|
||||
@ -1600,6 +1616,7 @@ void GMainWindow::ShutdownGame() {
|
||||
emu_speed_label->setVisible(false);
|
||||
game_fps_label->setVisible(false);
|
||||
emu_frametime_label->setVisible(false);
|
||||
notification_led->setColor(QColor(0, 0, 0));
|
||||
|
||||
UpdateSaveStates();
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <QTranslator>
|
||||
#include "citra_qt/compatibility_list.h"
|
||||
#include "citra_qt/hotkeys.h"
|
||||
#include "citra_qt/notification_led.h"
|
||||
#include "citra_qt/user_data_migration.h"
|
||||
#include "core/core.h"
|
||||
#include "core/savestate.h"
|
||||
@ -147,6 +148,7 @@ signals:
|
||||
void CIAInstallReport(Service::AM::InstallStatus status, QString filepath);
|
||||
void CompressFinished(bool is_compress, bool success);
|
||||
void CIAInstallFinished();
|
||||
void InfoLEDColorChanged();
|
||||
// Signal that tells widgets to update icons to use the current theme
|
||||
void UpdateThemedIcons();
|
||||
|
||||
@ -364,6 +366,8 @@ private:
|
||||
|
||||
MultiplayerState* multiplayer_state = nullptr;
|
||||
|
||||
LedWidget* notification_led = nullptr;
|
||||
|
||||
// Created before `config` to ensure that emu data directory
|
||||
// isn't created before the check is performed
|
||||
UserDataMigrator user_data_migrator;
|
||||
|
||||
87
src/citra_qt/notification_led.cpp
Normal file
87
src/citra_qt/notification_led.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <QPainter>
|
||||
#include <QRadialGradient>
|
||||
#include "citra_qt/notification_led.h"
|
||||
|
||||
LedWidget::LedWidget(QWidget* parent) : QWidget(parent), color(0, 0, 0) {
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
}
|
||||
|
||||
QSize LedWidget::sizeHint() const {
|
||||
return QSize(16, 16);
|
||||
}
|
||||
|
||||
QSize LedWidget::minimumSizeHint() const {
|
||||
return QSize(16, 16);
|
||||
}
|
||||
|
||||
void LedWidget::setColor(const QColor& _color) {
|
||||
if (color == _color)
|
||||
return;
|
||||
|
||||
color = _color;
|
||||
update();
|
||||
}
|
||||
|
||||
QColor LedWidget::lerpColor(const QColor& a, const QColor& b, float t) {
|
||||
t = std::clamp(t, 0.0f, 1.0f);
|
||||
|
||||
return QColor(int(a.red() + (b.red() - a.red()) * t),
|
||||
int(a.green() + (b.green() - a.green()) * t),
|
||||
int(a.blue() + (b.blue() - a.blue()) * t));
|
||||
}
|
||||
|
||||
QColor LedWidget::blendLedColor(int r, int g, int b) const {
|
||||
// Default "off" color
|
||||
const QColor off_color(64, 64, 64);
|
||||
|
||||
// If completely off, just show gray and skip further calculations
|
||||
if (r == 0 && g == 0 && b == 0)
|
||||
return off_color;
|
||||
|
||||
// Normalize lit color so hue stays pure
|
||||
int max_c = std::max({r, g, b});
|
||||
QColor lit_color((r * 255) / max_c, (g * 255) / max_c, (b * 255) / max_c);
|
||||
|
||||
// Convert PWM duty to perceived brightness.
|
||||
// This gives better results as LED RGB values
|
||||
// are not linear.
|
||||
constexpr float gamma = 2.4f;
|
||||
float pwm = max_c / 255.0;
|
||||
float t = std::powf(pwm, 1.f / gamma);
|
||||
|
||||
return lerpColor(off_color, lit_color, t * 0.8f);
|
||||
}
|
||||
|
||||
void LedWidget::paintEvent(QPaintEvent*) {
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QRectF rect = this->rect().adjusted(0, 2, 0, -2);
|
||||
|
||||
qreal size = std::min(rect.width(), rect.height());
|
||||
QRectF circle((rect.center().x() - size / 2.f) - 2, rect.center().y() - size / 2.f, size, size);
|
||||
|
||||
QPointF center = circle.center();
|
||||
qreal radius = circle.width() / 2.f;
|
||||
|
||||
QColor base = blendLedColor(color.red(), color.green(), color.blue());
|
||||
|
||||
QRadialGradient g(center, radius);
|
||||
|
||||
QColor inner = base.lighter(135);
|
||||
QColor outer = base.darker(125);
|
||||
|
||||
g.setColorAt(0.f, inner);
|
||||
g.setColorAt(0.7f, base);
|
||||
g.setColorAt(1.f, outer);
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(g);
|
||||
p.drawEllipse(circle);
|
||||
}
|
||||
30
src/citra_qt/notification_led.h
Normal file
30
src/citra_qt/notification_led.h
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QColor>
|
||||
#include <QWidget>
|
||||
|
||||
class LedWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LedWidget(QWidget* parent = nullptr);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
void setColor(const QColor& color);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
private:
|
||||
QColor blendLedColor(int r, int g, int b) const;
|
||||
static QColor lerpColor(const QColor& a, const QColor& b, float t);
|
||||
|
||||
private:
|
||||
QColor color;
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user