yolobs-studio/UI/window-projector.cpp

160 lines
3.7 KiB
C++
Raw Normal View History

2016-02-23 23:16:51 +00:00
#include <QAction>
2017-04-19 19:54:15 +00:00
#include <QGuiApplication>
2016-02-23 23:16:51 +00:00
#include <QMouseEvent>
#include <QMenu>
2017-04-19 19:54:15 +00:00
#include <QScreen>
2016-02-23 23:16:51 +00:00
#include "window-projector.hpp"
#include "display-helpers.hpp"
#include "qt-wrappers.hpp"
#include "platform.hpp"
#include "obs-app.hpp"
2017-06-29 19:01:10 +00:00
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, bool window)
2016-02-23 23:16:51 +00:00
: OBSQTDisplay (widget,
2017-06-29 19:01:10 +00:00
Qt::Window),
2016-02-23 23:16:51 +00:00
source (source_),
removedSignal (obs_source_get_signal_handler(source),
2016-05-24 19:53:01 +00:00
"remove", OBSSourceRemoved, this)
2016-02-23 23:16:51 +00:00
{
2017-06-29 19:01:10 +00:00
if (!window) {
setWindowFlags(Qt::FramelessWindowHint |
Qt::X11BypassWindowManagerHint);
}
2016-02-23 23:16:51 +00:00
setAttribute(Qt::WA_DeleteOnClose, true);
2017-04-19 19:54:15 +00:00
//disable application quit when last window closed
setAttribute(Qt::WA_QuitOnClose, false);
2016-02-23 23:16:51 +00:00
installEventFilter(CreateShortcutFilter());
auto addDrawCallback = [this] ()
{
obs_display_add_draw_callback(GetDisplay(), OBSRender, this);
obs_display_set_background_color(GetDisplay(), 0x000000);
};
connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback);
2016-08-28 12:07:43 +00:00
bool hideCursor = config_get_bool(GetGlobalConfig(),
"BasicWindow", "HideProjectorCursor");
2017-06-29 19:01:10 +00:00
if (hideCursor && !window) {
2016-08-28 12:07:43 +00:00
QPixmap empty(16, 16);
empty.fill(Qt::transparent);
setCursor(QCursor(empty));
}
2016-02-23 23:16:51 +00:00
App()->IncrementSleepInhibition();
2017-06-29 19:01:10 +00:00
resize(480, 270);
2016-02-23 23:16:51 +00:00
}
OBSProjector::~OBSProjector()
{
if (source)
obs_source_dec_showing(source);
App()->DecrementSleepInhibition();
}
2017-06-29 19:01:10 +00:00
void OBSProjector::Init(int monitor, bool window, QString title)
2016-02-23 23:16:51 +00:00
{
2017-04-19 19:54:15 +00:00
QScreen *screen = QGuiApplication::screens()[monitor];
2016-02-23 23:16:51 +00:00
2017-06-29 19:01:10 +00:00
if (!window)
setGeometry(screen->geometry());
2016-02-23 23:16:51 +00:00
2016-10-10 19:01:40 +00:00
bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
"BasicWindow", "ProjectorAlwaysOnTop");
2017-06-29 19:01:10 +00:00
if (alwaysOnTop && !window)
2016-10-10 19:01:40 +00:00
SetAlwaysOnTop(this, true);
2017-06-29 19:01:10 +00:00
if (window)
setWindowTitle(title);
2016-02-23 23:16:51 +00:00
show();
if (source)
obs_source_inc_showing(source);
2017-06-29 19:01:10 +00:00
if (!window) {
QAction *action = new QAction(this);
action->setShortcut(Qt::Key_Escape);
addAction(action);
connect(action, SIGNAL(triggered()), this,
SLOT(EscapeTriggered()));
}
2017-04-19 19:54:15 +00:00
savedMonitor = monitor;
2017-06-29 19:01:10 +00:00
isWindow = window;
2016-02-23 23:16:51 +00:00
}
void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
{
OBSProjector *window = reinterpret_cast<OBSProjector*>(data);
uint32_t targetCX;
uint32_t targetCY;
int x, y;
int newCX, newCY;
float scale;
if (window->source) {
targetCX = std::max(obs_source_get_width(window->source), 1u);
targetCY = std::max(obs_source_get_height(window->source), 1u);
} else {
struct obs_video_info ovi;
obs_get_video_info(&ovi);
targetCX = ovi.base_width;
targetCY = ovi.base_height;
}
GetScaleAndCenterPos(targetCX, targetCY, cx, cy, x, y, scale);
newCX = int(scale * float(targetCX));
newCY = int(scale * float(targetCY));
gs_viewport_push();
gs_projection_push();
gs_ortho(0.0f, float(targetCX), 0.0f, float(targetCY), -100.0f, 100.0f);
gs_set_viewport(x, y, newCX, newCY);
if (window->source)
obs_source_video_render(window->source);
else
obs_render_main_view();
gs_projection_pop();
gs_viewport_pop();
}
void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params)
{
OBSProjector *window = reinterpret_cast<OBSProjector*>(data);
2017-04-19 19:54:15 +00:00
2016-02-23 23:16:51 +00:00
window->deleteLater();
UNUSED_PARAMETER(params);
}
void OBSProjector::mousePressEvent(QMouseEvent *event)
{
OBSQTDisplay::mousePressEvent(event);
if (event->button() == Qt::RightButton) {
QMenu popup(this);
popup.addAction(QTStr("Close"), this, SLOT(EscapeTriggered()));
popup.exec(QCursor::pos());
}
}
void OBSProjector::EscapeTriggered()
{
2017-06-29 19:01:10 +00:00
if (!isWindow) {
OBSBasic *main =
reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
main->RemoveSavedProjectors(savedMonitor);
}
2017-04-19 19:54:15 +00:00
2016-02-23 23:16:51 +00:00
deleteLater();
}