frontend: Split Qt UI Widget implementations into single files per class

This commit is contained in:
PatTheMav
2025-01-08 17:33:13 +01:00
parent 9f887c76d3
commit 654ddcd409
58 changed files with 1723 additions and 253301 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+46 -5
View File
@@ -1,10 +1,15 @@
#pragma once
#include <future>
#include <memory>
#include <string>
#include <utility/MultitrackVideoOutput.hpp>
#include "multitrack-video-output.hpp"
#include <obs.hpp>
#include <util/dstr.hpp>
#include <future>
#define RTMP_PROTOCOL "rtmp"
#define SRT_PROTOCOL "srt"
#define RIST_PROTOCOL "rist"
class OBSBasic;
@@ -58,7 +63,7 @@ struct BasicOutputHandler {
OBSSignal replayBufferStopping;
OBSSignal replayBufferSaved;
inline BasicOutputHandler(OBSBasic *main_);
BasicOutputHandler(OBSBasic *main_);
virtual ~BasicOutputHandler(){};
@@ -103,3 +108,39 @@ protected:
BasicOutputHandler *CreateSimpleOutputHandler(OBSBasic *main);
BasicOutputHandler *CreateAdvancedOutputHandler(OBSBasic *main);
void OBSStreamStarting(void *data, calldata_t *params);
void OBSStreamStopping(void *data, calldata_t *params);
void OBSStartStreaming(void *data, calldata_t *params);
void OBSStopStreaming(void *data, calldata_t *params);
void OBSStartRecording(void *data, calldata_t *params);
void OBSStopRecording(void *data, calldata_t *params);
void OBSRecordStopping(void *data, calldata_t *params);
void OBSRecordFileChanged(void *data, calldata_t *params);
void OBSStartReplayBuffer(void *data, calldata_t *params);
void OBSStopReplayBuffer(void *data, calldata_t *params);
void OBSReplayBufferStopping(void *data, calldata_t *params);
void OBSReplayBufferSaved(void *data, calldata_t *params);
inline bool can_use_output(const char *prot, const char *output, const char *prot_test1,
const char *prot_test2 = nullptr)
{
return (strcmp(prot, prot_test1) == 0 || (prot_test2 && strcmp(prot, prot_test2) == 0)) &&
(obs_get_output_flags(output) & OBS_OUTPUT_SERVICE) != 0;
}
const char *GetStreamOutputType(const obs_service_t *service);
inline bool ServiceSupportsVodTrack(const char *service)
{
static const char *vodTrackServices[] = {"Twitch"};
for (const char *vodTrackService : vodTrackServices) {
if (astrcmpi(vodTrackService, service) == 0)
return true;
}
return false;
}
void clear_archive_encoder(obs_output_t *output, const char *expected_name);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+5 -38
View File
@@ -15,8 +15,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include "window-basic-main.hpp"
#include "screenshot-obj.hpp"
#include "ScreenshotObj.hpp"
#include <widgets/OBSBasic.hpp>
#include <qt-wrappers.hpp>
@@ -27,9 +28,9 @@
#pragma comment(lib, "windowscodecs.lib")
#endif
static void ScreenshotTick(void *param, float);
#include "moc_ScreenshotObj.cpp"
/* ========================================================================= */
static void ScreenshotTick(void *param, float);
ScreenshotObj::ScreenshotObj(obs_source_t *source) : weakSource(OBSGetWeakRef(source))
{
@@ -278,8 +279,6 @@ void ScreenshotObj::MuxAndFinish()
deleteLater();
}
/* ========================================================================= */
#define STAGE_SCREENSHOT 0
#define STAGE_DOWNLOAD 1
#define STAGE_COPY_AND_SAVE 2
@@ -313,35 +312,3 @@ static void ScreenshotTick(void *param, float)
data->stage++;
}
void OBSBasic::Screenshot(OBSSource source)
{
if (!!screenshotData) {
blog(LOG_WARNING, "Cannot take new screenshot, "
"screenshot currently in progress");
return;
}
screenshotData = new ScreenshotObj(source);
}
void OBSBasic::ScreenshotSelectedSource()
{
OBSSceneItem item = GetCurrentSceneItem();
if (item) {
Screenshot(obs_sceneitem_get_source(item));
} else {
blog(LOG_INFO, "Could not take a source screenshot: "
"no source selected");
}
}
void OBSBasic::ScreenshotProgram()
{
Screenshot(GetProgramSource());
}
void OBSBasic::ScreenshotScene()
{
Screenshot(GetCurrentSceneSource());
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4 -209
View File
@@ -1,25 +1,9 @@
#include "moc_qt-display.cpp"
#include "display-helpers.hpp"
#include <QWindow>
#include <QScreen>
#include <QResizeEvent>
#include <QShowEvent>
#pragma once
#include <qt-wrappers.hpp>
#include <obs-config.h>
#include <widgets/OBSQTDisplay.hpp>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
#if !defined(_WIN32) && !defined(__APPLE__)
#include <obs-nix-platform.h>
#endif
#ifdef ENABLE_WAYLAND
#include <qpa/qplatformnativeinterface.h>
#endif
#include <QObject>
#include <QPlatformSurfaceEvent>
class SurfaceEventFilter : public QObject {
OBSQTDisplay *display;
@@ -52,192 +36,3 @@ protected:
return result;
}
};
static inline long long color_to_int(const QColor &color)
{
auto shift = [&](unsigned val, int shift) {
return ((val & 0xff) << shift);
};
return shift(color.red(), 0) | shift(color.green(), 8) | shift(color.blue(), 16) | shift(color.alpha(), 24);
}
static inline QColor rgba_to_color(uint32_t rgba)
{
return QColor::fromRgb(rgba & 0xFF, (rgba >> 8) & 0xFF, (rgba >> 16) & 0xFF, (rgba >> 24) & 0xFF);
}
static bool QTToGSWindow(QWindow *window, gs_window &gswindow)
{
bool success = true;
#ifdef _WIN32
gswindow.hwnd = (HWND)window->winId();
#elif __APPLE__
gswindow.view = (id)window->winId();
#else
switch (obs_get_nix_platform()) {
case OBS_NIX_PLATFORM_X11_EGL:
gswindow.id = window->winId();
gswindow.display = obs_get_nix_platform_display();
break;
#ifdef ENABLE_WAYLAND
case OBS_NIX_PLATFORM_WAYLAND: {
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
gswindow.display = native->nativeResourceForWindow("surface", window);
success = gswindow.display != nullptr;
break;
}
#endif
default:
success = false;
break;
}
#endif
return success;
}
OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags)
{
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_StaticContents);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_DontCreateNativeAncestors);
setAttribute(Qt::WA_NativeWindow);
auto windowVisible = [this](bool visible) {
if (!visible) {
#if !defined(_WIN32) && !defined(__APPLE__)
display = nullptr;
#endif
return;
}
if (!display) {
CreateDisplay();
} else {
QSize size = GetPixelSize(this);
obs_display_resize(display, size.width(), size.height());
}
};
auto screenChanged = [this](QScreen *) {
CreateDisplay();
QSize size = GetPixelSize(this);
obs_display_resize(display, size.width(), size.height());
};
connect(windowHandle(), &QWindow::visibleChanged, windowVisible);
connect(windowHandle(), &QWindow::screenChanged, screenChanged);
windowHandle()->installEventFilter(new SurfaceEventFilter(this));
}
QColor OBSQTDisplay::GetDisplayBackgroundColor() const
{
return rgba_to_color(backgroundColor);
}
void OBSQTDisplay::SetDisplayBackgroundColor(const QColor &color)
{
uint32_t newBackgroundColor = (uint32_t)color_to_int(color);
if (newBackgroundColor != backgroundColor) {
backgroundColor = newBackgroundColor;
UpdateDisplayBackgroundColor();
}
}
void OBSQTDisplay::UpdateDisplayBackgroundColor()
{
obs_display_set_background_color(display, backgroundColor);
}
void OBSQTDisplay::CreateDisplay()
{
if (display)
return;
if (destroying)
return;
if (!windowHandle()->isExposed())
return;
QSize size = GetPixelSize(this);
gs_init_data info = {};
info.cx = size.width();
info.cy = size.height();
info.format = GS_BGRA;
info.zsformat = GS_ZS_NONE;
if (!QTToGSWindow(windowHandle(), info.window))
return;
display = obs_display_create(&info, backgroundColor);
emit DisplayCreated(this);
}
void OBSQTDisplay::paintEvent(QPaintEvent *event)
{
CreateDisplay();
QWidget::paintEvent(event);
}
void OBSQTDisplay::moveEvent(QMoveEvent *event)
{
QWidget::moveEvent(event);
OnMove();
}
bool OBSQTDisplay::nativeEvent(const QByteArray &, void *message, qintptr *)
{
#ifdef _WIN32
const MSG &msg = *static_cast<MSG *>(message);
switch (msg.message) {
case WM_DISPLAYCHANGE:
OnDisplayChange();
}
#else
UNUSED_PARAMETER(message);
#endif
return false;
}
void OBSQTDisplay::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
CreateDisplay();
if (isVisible() && display) {
QSize size = GetPixelSize(this);
obs_display_resize(display, size.width(), size.height());
}
emit DisplayResized();
}
QPaintEngine *OBSQTDisplay::paintEngine() const
{
return nullptr;
}
void OBSQTDisplay::OnMove()
{
if (display)
obs_display_update_color_space(display);
}
void OBSQTDisplay::OnDisplayChange()
{
if (display)
obs_display_update_color_space(display);
}
File diff suppressed because it is too large Load Diff
+1 -323
View File
@@ -1,230 +1,8 @@
#pragma once
#include <obs.hpp>
#include <QWidget>
#include <QPaintEvent>
#include <QTimer>
#include <QMutex>
#include <QList>
#include <QMenu>
#include <QAccessibleWidget>
#include "absolute-slider.hpp"
class QPushButton;
class VolumeMeterTimer;
class VolumeSlider;
class VolumeMeter : public QWidget {
Q_OBJECT
Q_PROPERTY(QColor backgroundNominalColor READ getBackgroundNominalColor WRITE setBackgroundNominalColor
DESIGNABLE true)
Q_PROPERTY(QColor backgroundWarningColor READ getBackgroundWarningColor WRITE setBackgroundWarningColor
DESIGNABLE true)
Q_PROPERTY(
QColor backgroundErrorColor READ getBackgroundErrorColor WRITE setBackgroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundNominalColor READ getForegroundNominalColor WRITE setForegroundNominalColor
DESIGNABLE true)
Q_PROPERTY(QColor foregroundWarningColor READ getForegroundWarningColor WRITE setForegroundWarningColor
DESIGNABLE true)
Q_PROPERTY(
QColor foregroundErrorColor READ getForegroundErrorColor WRITE setForegroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundNominalColorDisabled READ getBackgroundNominalColorDisabled WRITE
setBackgroundNominalColorDisabled DESIGNABLE true)
Q_PROPERTY(QColor backgroundWarningColorDisabled READ getBackgroundWarningColorDisabled WRITE
setBackgroundWarningColorDisabled DESIGNABLE true)
Q_PROPERTY(QColor backgroundErrorColorDisabled READ getBackgroundErrorColorDisabled WRITE
setBackgroundErrorColorDisabled DESIGNABLE true)
Q_PROPERTY(QColor foregroundNominalColorDisabled READ getForegroundNominalColorDisabled WRITE
setForegroundNominalColorDisabled DESIGNABLE true)
Q_PROPERTY(QColor foregroundWarningColorDisabled READ getForegroundWarningColorDisabled WRITE
setForegroundWarningColorDisabled DESIGNABLE true)
Q_PROPERTY(QColor foregroundErrorColorDisabled READ getForegroundErrorColorDisabled WRITE
setForegroundErrorColorDisabled DESIGNABLE true)
Q_PROPERTY(QColor clipColor READ getClipColor WRITE setClipColor DESIGNABLE true)
Q_PROPERTY(QColor magnitudeColor READ getMagnitudeColor WRITE setMagnitudeColor DESIGNABLE true)
Q_PROPERTY(QColor majorTickColor READ getMajorTickColor WRITE setMajorTickColor DESIGNABLE true)
Q_PROPERTY(QColor minorTickColor READ getMinorTickColor WRITE setMinorTickColor DESIGNABLE true)
Q_PROPERTY(int meterThickness READ getMeterThickness WRITE setMeterThickness DESIGNABLE true)
Q_PROPERTY(qreal meterFontScaling READ getMeterFontScaling WRITE setMeterFontScaling DESIGNABLE true)
// Levels are denoted in dBFS.
Q_PROPERTY(qreal minimumLevel READ getMinimumLevel WRITE setMinimumLevel DESIGNABLE true)
Q_PROPERTY(qreal warningLevel READ getWarningLevel WRITE setWarningLevel DESIGNABLE true)
Q_PROPERTY(qreal errorLevel READ getErrorLevel WRITE setErrorLevel DESIGNABLE true)
Q_PROPERTY(qreal clipLevel READ getClipLevel WRITE setClipLevel DESIGNABLE true)
Q_PROPERTY(qreal minimumInputLevel READ getMinimumInputLevel WRITE setMinimumInputLevel DESIGNABLE true)
// Rates are denoted in dB/second.
Q_PROPERTY(qreal peakDecayRate READ getPeakDecayRate WRITE setPeakDecayRate DESIGNABLE true)
// Time in seconds for the VU meter to integrate over.
Q_PROPERTY(qreal magnitudeIntegrationTime READ getMagnitudeIntegrationTime WRITE setMagnitudeIntegrationTime
DESIGNABLE true)
// Duration is denoted in seconds.
Q_PROPERTY(qreal peakHoldDuration READ getPeakHoldDuration WRITE setPeakHoldDuration DESIGNABLE true)
Q_PROPERTY(qreal inputPeakHoldDuration READ getInputPeakHoldDuration WRITE setInputPeakHoldDuration
DESIGNABLE true)
friend class VolControl;
private:
obs_volmeter_t *obs_volmeter;
static std::weak_ptr<VolumeMeterTimer> updateTimer;
std::shared_ptr<VolumeMeterTimer> updateTimerRef;
inline void resetLevels();
inline void doLayout();
inline bool detectIdle(uint64_t ts);
inline void calculateBallistics(uint64_t ts, qreal timeSinceLastRedraw = 0.0);
inline void calculateBallisticsForChannel(int channelNr, uint64_t ts, qreal timeSinceLastRedraw);
inline int convertToInt(float number);
void paintInputMeter(QPainter &painter, int x, int y, int width, int height, float peakHold);
void paintHMeter(QPainter &painter, int x, int y, int width, int height, float magnitude, float peak,
float peakHold);
void paintHTicks(QPainter &painter, int x, int y, int width);
void paintVMeter(QPainter &painter, int x, int y, int width, int height, float magnitude, float peak,
float peakHold);
void paintVTicks(QPainter &painter, int x, int y, int height);
QMutex dataMutex;
bool recalculateLayout = true;
uint64_t currentLastUpdateTime = 0;
float currentMagnitude[MAX_AUDIO_CHANNELS];
float currentPeak[MAX_AUDIO_CHANNELS];
float currentInputPeak[MAX_AUDIO_CHANNELS];
int displayNrAudioChannels = 0;
float displayMagnitude[MAX_AUDIO_CHANNELS];
float displayPeak[MAX_AUDIO_CHANNELS];
float displayPeakHold[MAX_AUDIO_CHANNELS];
uint64_t displayPeakHoldLastUpdateTime[MAX_AUDIO_CHANNELS];
float displayInputPeakHold[MAX_AUDIO_CHANNELS];
uint64_t displayInputPeakHoldLastUpdateTime[MAX_AUDIO_CHANNELS];
QFont tickFont;
QColor backgroundNominalColor;
QColor backgroundWarningColor;
QColor backgroundErrorColor;
QColor foregroundNominalColor;
QColor foregroundWarningColor;
QColor foregroundErrorColor;
QColor backgroundNominalColorDisabled;
QColor backgroundWarningColorDisabled;
QColor backgroundErrorColorDisabled;
QColor foregroundNominalColorDisabled;
QColor foregroundWarningColorDisabled;
QColor foregroundErrorColorDisabled;
QColor clipColor;
QColor magnitudeColor;
QColor majorTickColor;
QColor minorTickColor;
int meterThickness;
qreal meterFontScaling;
qreal minimumLevel;
qreal warningLevel;
qreal errorLevel;
qreal clipLevel;
qreal minimumInputLevel;
qreal peakDecayRate;
qreal magnitudeIntegrationTime;
qreal peakHoldDuration;
qreal inputPeakHoldDuration;
QColor p_backgroundNominalColor;
QColor p_backgroundWarningColor;
QColor p_backgroundErrorColor;
QColor p_foregroundNominalColor;
QColor p_foregroundWarningColor;
QColor p_foregroundErrorColor;
uint64_t lastRedrawTime = 0;
int channels = 0;
bool clipping = false;
bool vertical;
bool muted = false;
public:
explicit VolumeMeter(QWidget *parent = nullptr, obs_volmeter_t *obs_volmeter = nullptr, bool vertical = false);
~VolumeMeter();
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS], const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
QRect getBarRect() const;
bool needLayoutChange();
QColor getBackgroundNominalColor() const;
void setBackgroundNominalColor(QColor c);
QColor getBackgroundWarningColor() const;
void setBackgroundWarningColor(QColor c);
QColor getBackgroundErrorColor() const;
void setBackgroundErrorColor(QColor c);
QColor getForegroundNominalColor() const;
void setForegroundNominalColor(QColor c);
QColor getForegroundWarningColor() const;
void setForegroundWarningColor(QColor c);
QColor getForegroundErrorColor() const;
void setForegroundErrorColor(QColor c);
QColor getBackgroundNominalColorDisabled() const;
void setBackgroundNominalColorDisabled(QColor c);
QColor getBackgroundWarningColorDisabled() const;
void setBackgroundWarningColorDisabled(QColor c);
QColor getBackgroundErrorColorDisabled() const;
void setBackgroundErrorColorDisabled(QColor c);
QColor getForegroundNominalColorDisabled() const;
void setForegroundNominalColorDisabled(QColor c);
QColor getForegroundWarningColorDisabled() const;
void setForegroundWarningColorDisabled(QColor c);
QColor getForegroundErrorColorDisabled() const;
void setForegroundErrorColorDisabled(QColor c);
QColor getClipColor() const;
void setClipColor(QColor c);
QColor getMagnitudeColor() const;
void setMagnitudeColor(QColor c);
QColor getMajorTickColor() const;
void setMajorTickColor(QColor c);
QColor getMinorTickColor() const;
void setMinorTickColor(QColor c);
int getMeterThickness() const;
void setMeterThickness(int v);
qreal getMeterFontScaling() const;
void setMeterFontScaling(qreal v);
qreal getMinimumLevel() const;
void setMinimumLevel(qreal v);
qreal getWarningLevel() const;
void setWarningLevel(qreal v);
qreal getErrorLevel() const;
void setErrorLevel(qreal v);
qreal getClipLevel() const;
void setClipLevel(qreal v);
qreal getMinimumInputLevel() const;
void setMinimumInputLevel(qreal v);
qreal getPeakDecayRate() const;
void setPeakDecayRate(qreal v);
qreal getMagnitudeIntegrationTime() const;
void setMagnitudeIntegrationTime(qreal v);
qreal getPeakHoldDuration() const;
void setPeakHoldDuration(qreal v);
qreal getInputPeakHoldDuration() const;
void setInputPeakHoldDuration(qreal v);
void setPeakMeterType(enum obs_peak_meter_type peakMeterType);
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void wheelEvent(QWheelEvent *event) override;
protected:
void paintEvent(QPaintEvent *event) override;
void changeEvent(QEvent *e) override;
};
class VolumeMeter;
class VolumeMeterTimer : public QTimer {
Q_OBJECT
@@ -239,103 +17,3 @@ protected:
void timerEvent(QTimerEvent *event) override;
QList<VolumeMeter *> volumeMeters;
};
class QLabel;
class VolumeSlider;
class MuteCheckBox;
class OBSSourceLabel;
class VolControl : public QFrame {
Q_OBJECT
private:
OBSSource source;
std::vector<OBSSignal> sigs;
OBSSourceLabel *nameLabel;
QLabel *volLabel;
VolumeMeter *volMeter;
VolumeSlider *slider;
MuteCheckBox *mute;
QPushButton *config = nullptr;
float levelTotal;
float levelCount;
OBSFader obs_fader;
OBSVolMeter obs_volmeter;
bool vertical;
QMenu *contextMenu;
static void OBSVolumeChanged(void *param, float db);
static void OBSVolumeLevel(void *data, const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS], const float inputPeak[MAX_AUDIO_CHANNELS]);
static void OBSVolumeMuted(void *data, calldata_t *calldata);
static void OBSMixersOrMonitoringChanged(void *data, calldata_t *);
void EmitConfigClicked();
private slots:
void VolumeChanged();
void VolumeMuted(bool muted);
void MixersOrMonitoringChanged();
void SetMuted(bool checked);
void SliderChanged(int vol);
void updateText();
signals:
void ConfigClicked();
public:
explicit VolControl(OBSSource source, bool showConfig = false, bool vertical = false);
~VolControl();
inline obs_source_t *GetSource() const { return source; }
void SetMeterDecayRate(qreal q);
void setPeakMeterType(enum obs_peak_meter_type peakMeterType);
void EnableSlider(bool enable);
inline void SetContextMenu(QMenu *cm) { contextMenu = cm; }
void refreshColors();
};
class VolumeSlider : public AbsoluteSlider {
Q_OBJECT
public:
obs_fader_t *fad;
VolumeSlider(obs_fader_t *fader, QWidget *parent = nullptr);
VolumeSlider(obs_fader_t *fader, Qt::Orientation orientation, QWidget *parent = nullptr);
bool getDisplayTicks() const;
void setDisplayTicks(bool display);
private:
bool displayTicks = false;
QColor tickColor;
protected:
virtual void paintEvent(QPaintEvent *event) override;
};
class VolumeAccessibleInterface : public QAccessibleWidget {
public:
VolumeAccessibleInterface(QWidget *w);
QVariant currentValue() const;
void setCurrentValue(const QVariant &value);
QVariant maximumValue() const;
QVariant minimumValue() const;
QVariant minimumStepSize() const;
private:
VolumeSlider *slider() const;
protected:
virtual QAccessible::Role role() const override;
virtual QString text(QAccessible::Text t) const override;
};