mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-05-14 10:24:12 -04:00
197 lines
4.4 KiB
C++
197 lines
4.4 KiB
C++
/******************************************************************************
|
|
Copyright (C) 2025 by Taylor Giampaolo <warchamp7@obsproject.com>
|
|
Lain Bailey <lain@obsproject.com>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
******************************************************************************/
|
|
|
|
#include "ThumbnailItem.hpp"
|
|
|
|
#include <utility/ScreenshotObj.hpp>
|
|
#include <utility/ThumbnailView.hpp>
|
|
#include <widgets/OBSBasic.hpp>
|
|
|
|
#include <QIcon>
|
|
#include <QPainter>
|
|
#include <QPixmap>
|
|
|
|
static constexpr int kDefaultWidth = 320;
|
|
static constexpr int kDefaultHeight = 180;
|
|
|
|
namespace {
|
|
QPixmap getDefaultThumbnail(obs_source_t *source)
|
|
{
|
|
const char *id = obs_source_get_id(source);
|
|
OBSBasic *main = OBSBasic::Get();
|
|
if (main && id) {
|
|
QIcon icon = OBSBasic::Get()->GetSourceIcon(id);
|
|
QPixmap iconPixmap = icon.pixmap(90, 90);
|
|
|
|
QPixmap defaultPixmap(kDefaultWidth, kDefaultHeight);
|
|
defaultPixmap.fill(Qt::transparent);
|
|
|
|
QPainter painter(&defaultPixmap);
|
|
|
|
const int x = (defaultPixmap.width() - iconPixmap.width()) / 2;
|
|
const int y = (defaultPixmap.height() - iconPixmap.height()) / 2;
|
|
|
|
painter.drawPixmap(x, y, iconPixmap);
|
|
|
|
return defaultPixmap;
|
|
}
|
|
|
|
return QPixmap();
|
|
}
|
|
} // namespace
|
|
|
|
ThumbnailItem::ThumbnailItem(const std::string &uuid, ThumbnailManager *manager) : QObject(manager), uuid(uuid)
|
|
{
|
|
OBSSourceAutoRelease source = obs_get_source_by_uuid(uuid.c_str());
|
|
if (!source) {
|
|
return;
|
|
}
|
|
|
|
weakSource = OBSGetWeakRef(source);
|
|
|
|
std::optional<QPixmap> cachedPixmap = manager->getCachedPixmap(uuid);
|
|
if (cachedPixmap.has_value()) {
|
|
setPixmap(cachedPixmap.value());
|
|
isDefaultPixmap_ = false;
|
|
} else {
|
|
setPixmap(getDefaultThumbnail(source));
|
|
}
|
|
|
|
if ((obs_source_get_output_flags(source) & OBS_SOURCE_VIDEO) != 0) {
|
|
isVideoSource = true;
|
|
}
|
|
}
|
|
|
|
void ThumbnailItem::updatePixmapFromImage(const QImage &image)
|
|
{
|
|
if (!image.isNull()) {
|
|
setPixmap(QPixmap::fromImage(image));
|
|
isDefaultPixmap_ = false;
|
|
}
|
|
}
|
|
|
|
bool ThumbnailItem::shouldUpdate() const
|
|
{
|
|
return isValid() && (viewCount > 0) && (enabledCount > 0);
|
|
}
|
|
|
|
QPixmap ThumbnailItem::getPixmap() const
|
|
{
|
|
return pixmap;
|
|
}
|
|
|
|
void ThumbnailItem::setPixmap(QPixmap pixmap)
|
|
{
|
|
this->pixmap = std::move(pixmap);
|
|
|
|
emit pixmapUpdated(this->pixmap);
|
|
}
|
|
|
|
void ThumbnailItem::incrementViewCount()
|
|
{
|
|
++viewCount;
|
|
}
|
|
|
|
ThumbnailView *ThumbnailItem::createView(QObject *parent)
|
|
{
|
|
auto *view = new ThumbnailView(parent, this);
|
|
|
|
incrementViewCount();
|
|
if (view->isEnabled()) {
|
|
incrementEnabledCount();
|
|
}
|
|
|
|
// Connect ThumbnailView signals
|
|
connect(view, &QObject::destroyed, this, [this, view]() {
|
|
decrementViewCount();
|
|
if (view->isEnabled()) {
|
|
decrementEnabledCount();
|
|
}
|
|
});
|
|
connect(view, &ThumbnailView::enabledChanged, this, [this](bool enabled) {
|
|
if (enabled) {
|
|
incrementEnabledCount();
|
|
} else {
|
|
decrementEnabledCount();
|
|
}
|
|
});
|
|
|
|
return view;
|
|
}
|
|
|
|
void ThumbnailItem::decrementViewCount()
|
|
{
|
|
if (viewCount > 0) {
|
|
--viewCount;
|
|
}
|
|
|
|
if (viewCount <= 0) {
|
|
emit noViewsRemaining();
|
|
}
|
|
}
|
|
|
|
void ThumbnailItem::incrementEnabledCount()
|
|
{
|
|
++enabledCount;
|
|
}
|
|
|
|
void ThumbnailItem::decrementEnabledCount()
|
|
{
|
|
if (enabledCount > 0) {
|
|
--enabledCount;
|
|
}
|
|
}
|
|
|
|
bool ThumbnailItem::update()
|
|
{
|
|
if (!isVideoSource) {
|
|
return false;
|
|
}
|
|
|
|
if (!shouldUpdate()) {
|
|
return false;
|
|
}
|
|
|
|
OBSSource source = OBSGetStrongRef(weakSource);
|
|
if (!source) {
|
|
return false;
|
|
}
|
|
|
|
QPixmap pixmap;
|
|
if (this->pixmap.isNull()) {
|
|
this->pixmap = pixmap;
|
|
}
|
|
|
|
if (source) {
|
|
uint32_t sourceWidth = obs_source_get_width(source);
|
|
uint32_t sourceHeight = obs_source_get_height(source);
|
|
|
|
if (sourceWidth == 0 || sourceHeight == 0) {
|
|
return false;
|
|
}
|
|
|
|
auto *obj = new ScreenshotObj(source);
|
|
obj->setSaveToFile(false);
|
|
obj->setSize(kDefaultWidth, kDefaultHeight);
|
|
|
|
connect(obj, &ScreenshotObj::imageReady, this, &ThumbnailItem::updatePixmapFromImage);
|
|
}
|
|
|
|
return true;
|
|
}
|