diff --git a/kstars/indi/streamform.ui b/kstars/indi/streamform.ui index 0f936934f..c54c5b319 100644 --- a/kstars/indi/streamform.ui +++ b/kstars/indi/streamform.ui @@ -1,397 +1,376 @@ streamForm 0 0 - 491 + 504 356 0 0 Video Stream 3 3 3 3 3 3 32 32 64 64 Start recording 32 32 32 32 64 64 Recording options 32 32 32 32 64 64 Reset frame 32 32 Qt::Vertical - - - true - - - - 32 - 32 - - - - Zoom in - - - - - - - 32 - 32 - - - - - - - - true - - - - 32 - 32 - + + + + 0 + 0 + - Zoom out - - - - - - - 32 - 32 - + Zoom level + + + 1x + + + + + 5x + + + + + 10x + + 3 - - + + false + + + 0 + 0 + + - 32 - 32 + 100 + 0 - - + + Move zoomed view Up/Down + + + Qt::Horizontal false 0 0 100 0 Move zoomed view Left/Right Qt::Horizontal - - + + false - - - 0 - 0 - - - 100 - 0 + 32 + 32 - - Move zoomed view Up/Down - - - Qt::Horizontal + + Qt::Horizontal QSizePolicy::Preferred 40 20 FPS - + 0 0 Target FPS 1 60 32 32 Apply FPS and restart stream - + + .. 24 24 FPS: 50 0 Average FPS font-weight:bold; QFrame::NoFrame QFrame::Plain -- Qt::AlignCenter 0 0 320 240 false background-color:black; Qt::AlignCenter VideoWG QLabel
indi/videowg.h
diff --git a/kstars/indi/streamwg.cpp b/kstars/indi/streamwg.cpp index 518e1eaa5..6cdf7d34a 100644 --- a/kstars/indi/streamwg.cpp +++ b/kstars/indi/streamwg.cpp @@ -1,341 +1,331 @@ /* Stream Widget Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This application 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. 2004-03-16: A class to handle video streaming. */ #include "streamwg.h" #include "indistd.h" #include "driverinfo.h" #include "clientmanager.h" #include "kstars.h" #include "Options.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include RecordOptions::RecordOptions(QWidget *parent) : QDialog(parent) { #ifdef Q_OS_OSX setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); #endif setupUi(this); dirPath = QUrl::fromLocalFile(QDir::homePath()); selectDirB->setIcon( QIcon::fromTheme("document-open-folder")); connect(selectDirB, SIGNAL(clicked()), this, SLOT(selectRecordDirectory())); } void RecordOptions::selectRecordDirectory() { QString dir = QFileDialog::getExistingDirectory(KStars::Instance(), i18n("SER Record Directory"), dirPath.toLocalFile()); if (dir.isEmpty()) return; recordDirectoryEdit->setText(dir); } StreamWG::StreamWG(ISD::CCD *ccd) : QDialog(KStars::Instance()) { setupUi(this); currentCCD = ccd; streamWidth = streamHeight = -1; processStream = colorFrame = isRecording = false; options = new RecordOptions(this); connect(optionsB, SIGNAL(clicked()), options, SLOT(show())); QString filename, directory; ccd->getSERNameDirectory(filename, directory); double duration = 0.1; currentCCD->getStreamExposure(&duration); targetFPSSpin->setValue(1.0 / duration); options->recordFilenameEdit->setText(filename); options->recordDirectoryEdit->setText(directory); setWindowTitle(i18n("%1 Live Video", ccd->getDeviceName())); #ifdef Q_OS_OSX setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); #endif recordIcon = QIcon::fromTheme("media-record"); stopIcon = QIcon::fromTheme("media-playback-stop"); optionsB->setIcon(QIcon::fromTheme("run-build")); resetFrameB->setIcon(QIcon::fromTheme("view-restore")); connect(resetFrameB, SIGNAL(clicked()), this, SLOT(resetFrame())); recordB->setIcon(recordIcon); connect(recordB, SIGNAL(clicked()), this, SLOT(toggleRecord())); connect(ccd, SIGNAL(videoRecordToggled(bool)), this, SLOT(updateRecordStatus(bool))); connect(videoFrame, &VideoWG::newSelection, this, &StreamWG::setStreamingFrame); connect(videoFrame, &VideoWG::imageChanged, this, &StreamWG::imageChanged); resize(Options::streamWindowWidth(), Options::streamWindowHeight()); - zoomInB->setIcon(QIcon::fromTheme("zoom-in")); - zoomOutB->setIcon(QIcon::fromTheme("zoom-out")); - handLabel->setPixmap(QIcon::fromTheme("hand").pixmap(32, 32)); - eoszoom = currentCCD->getProperty("eoszoom"); if (eoszoom == nullptr) { - zoomInB->hide(); - zoomOutB->hide(); + zoomLevelCombo->hide(); } else { - connect(zoomInB, &QPushButton::clicked, [&]() + connect(zoomLevelCombo, static_cast(&QComboBox::activated), [&]() { ITextVectorProperty * tvp = eoszoom->getText(); - IUSaveText(&(tvp->tp[0]), "5"); - eoszoomActive = true; + QString zoomLevel = zoomLevelCombo->currentText().remove("x"); + IUSaveText(&(tvp->tp[0]), zoomLevel.toLatin1().constData()); handLabel->setEnabled(true); NSSlider->setEnabled(true); WESlider->setEnabled(true); + // Set it twice! currentCCD->getDriverInfo()->getClientManager()->sendNewText(tvp); - }); + QTimer::singleShot(1000, this, [ &, tvp]() + { + currentCCD->getDriverInfo()->getClientManager()->sendNewText(tvp); + }); - connect(zoomOutB, &QPushButton::clicked, [&]() - { - ITextVectorProperty * tvp = eoszoom->getText(); - IUSaveText(&(tvp->tp[0]), "0"); - eoszoomActive = false; - handLabel->setEnabled(false); - NSSlider->setEnabled(false); - WESlider->setEnabled(false); - currentCCD->getDriverInfo()->getClientManager()->sendNewText(tvp); }); } eoszoomposition = currentCCD->getProperty("eoszoomposition"); if (eoszoomposition == nullptr) { handLabel->hide(); NSSlider->hide(); WESlider->hide(); horizontalSpacer->changeSize(1, 1, QSizePolicy::Expanding); } else { connect(NSSlider, &QSlider::sliderReleased, [&]() { ITextVectorProperty * tvp = eoszoomposition->getText(); QString pos = QString("%1,%2").arg(WESlider->value()).arg(NSSlider->value()); IUSaveText(&(tvp->tp[0]), pos.toLatin1().constData()); currentCCD->getDriverInfo()->getClientManager()->sendNewText(tvp); }); connect(WESlider, &QSlider::sliderReleased, [&]() { ITextVectorProperty * tvp = eoszoomposition->getText(); QString pos = QString("%1,%2").arg(WESlider->value()).arg(NSSlider->value()); IUSaveText(&(tvp->tp[0]), pos.toLatin1().constData()); currentCCD->getDriverInfo()->getClientManager()->sendNewText(tvp); }); horizontalSpacer->changeSize(1, 1, QSizePolicy::Preferred); } connect(currentCCD, SIGNAL(newFPS(double, double)), this, SLOT(updateFPS(double, double))); connect(changeFPSB, &QPushButton::clicked, this, [&]() { if (currentCCD) { currentCCD->setStreamExposure(1.0 / targetFPSSpin->value()); currentCCD->setVideoStreamEnabled(false); QTimer::singleShot(1000, this, [&]() { currentCCD->setVideoStreamEnabled(true); }); } }); } QSize StreamWG::sizeHint() const { QSize size(Options::streamWindowWidth(), Options::streamWindowHeight()); return size; } void StreamWG::closeEvent(QCloseEvent * ev) { processStream = false; Options::setStreamWindowWidth(width()); Options::setStreamWindowHeight(height()); ev->accept(); emit hidden(); } void StreamWG::setColorFrame(bool color) { colorFrame = color; } void StreamWG::enableStream(bool enable) { if (enable) { processStream = true; show(); } else { processStream = false; //instFPS->setText("--"); avgFPS->setText("--"); hide(); } } void StreamWG::setSize(int wd, int ht) { if (wd != streamWidth || ht != streamHeight) { streamWidth = wd; streamHeight = ht; NSSlider->setMaximum(ht); NSSlider->setSingleStep(ht / 30); WESlider->setMaximum(wd); WESlider->setSingleStep(wd / 30); videoFrame->setSize(wd, ht); } } /*void StreamWG::resizeEvent(QResizeEvent *ev) { streamFrame->resize(ev->size().width() - layout()->margin() * 2, ev->size().height() - playB->height() - layout()->margin() * 4 - layout()->spacing()); }*/ void StreamWG::updateRecordStatus(bool enabled) { if ((enabled && isRecording) || (!enabled && !isRecording)) return; isRecording = enabled; if (isRecording) { recordB->setIcon(stopIcon); recordB->setToolTip(i18n("Stop recording")); } else { recordB->setIcon(recordIcon); recordB->setToolTip(i18n("Start recording")); } } void StreamWG::toggleRecord() { if (isRecording) { recordB->setIcon(recordIcon); isRecording = false; recordB->setToolTip(i18n("Start recording")); currentCCD->stopRecording(); } else { currentCCD->setSERNameDirectory(options->recordFilenameEdit->text(), options->recordDirectoryEdit->text()); // Save config in INDI so the filename and directory templates are reloaded next time currentCCD->setConfig(SAVE_CONFIG); if (options->recordUntilStoppedR->isChecked()) { isRecording = currentCCD->startRecording(); } else if (options->recordDurationR->isChecked()) { isRecording = currentCCD->startDurationRecording(options->durationSpin->value()); } else { isRecording = currentCCD->startFramesRecording(options->framesSpin->value()); } if (isRecording) { recordB->setIcon(stopIcon); recordB->setToolTip(i18n("Stop recording")); } } } void StreamWG::newFrame(IBLOB *bp) { bool rc = videoFrame->newFrame(bp); if (rc == false) qWarning() << "Failed to load video frame."; } void StreamWG::resetFrame() { currentCCD->resetStreamingFrame(); } void StreamWG::setStreamingFrame(QRect newFrame) { int w = newFrame.width(); // Must be divisable by 4 while (w % 4) { w++; } currentCCD->setStreamingFrame(newFrame.x(), newFrame.y(), w, newFrame.height()); } void StreamWG::updateFPS(double instantFPS, double averageFPS) { Q_UNUSED(instantFPS); //instFPS->setText(QString::number(instantFPS, 'f', 1)); avgFPS->setText(QString::number(averageFPS, 'f', 1)); } diff --git a/kstars/indi/streamwg.h b/kstars/indi/streamwg.h index 6116a856f..ea17645f7 100644 --- a/kstars/indi/streamwg.h +++ b/kstars/indi/streamwg.h @@ -1,93 +1,100 @@ /* Stream Widget Copyright (C) 2003-2017 Jasem Mutlaq (mutlaqja@ikarustech.com) This application 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. */ #pragma once #include "indi/indiccd.h" #include "ui_streamform.h" #include "ui_recordingoptions.h" #include #include #include #include #include #include #include #include #include #include class RecordOptions : public QDialog, public Ui::recordingOptions { - Q_OBJECT + Q_OBJECT - public: - explicit RecordOptions(QWidget *parent); + public: + explicit RecordOptions(QWidget *parent); - public slots: - void selectRecordDirectory(); + public slots: + void selectRecordDirectory(); - private: - QUrl dirPath; + private: + QUrl dirPath; - friend class StreamWG; + friend class StreamWG; }; class StreamWG : public QDialog, public Ui::streamForm { - Q_OBJECT - - public: - explicit StreamWG(ISD::CCD *ccd); - virtual ~StreamWG() override = default; - - void setColorFrame(bool color); - void setSize(int wd, int ht); - - void enableStream(bool enable); - bool isStreamEnabled() { return processStream; } - - void newFrame(IBLOB *bp); - - int getStreamWidth() { return streamWidth; } - int getStreamHeight() { return streamHeight; } - - protected: - void closeEvent(QCloseEvent *ev) override; - QSize sizeHint() const override; - - public slots: - void toggleRecord(); - void updateRecordStatus(bool enabled); - void resetFrame(); - - protected slots: - void setStreamingFrame(QRect newFrame); - void updateFPS(double instantFPS, double averageFPS); - - signals: - void hidden(); - void imageChanged(std::unique_ptr & frame); - - private: - bool processStream; - int streamWidth, streamHeight; - bool colorFrame, isRecording; - QIcon recordIcon, stopIcon; - ISD::CCD *currentCCD; - - // For Canon DSLRs - INDI::Property *eoszoom {nullptr}, *eoszoomposition {nullptr}; - bool eoszoomActive { false }; - - RecordOptions *options; + Q_OBJECT + + public: + explicit StreamWG(ISD::CCD *ccd); + virtual ~StreamWG() override = default; + + void setColorFrame(bool color); + void setSize(int wd, int ht); + + void enableStream(bool enable); + bool isStreamEnabled() + { + return processStream; + } + + void newFrame(IBLOB *bp); + + int getStreamWidth() + { + return streamWidth; + } + int getStreamHeight() + { + return streamHeight; + } + + protected: + void closeEvent(QCloseEvent *ev) override; + QSize sizeHint() const override; + + public slots: + void toggleRecord(); + void updateRecordStatus(bool enabled); + void resetFrame(); + + protected slots: + void setStreamingFrame(QRect newFrame); + void updateFPS(double instantFPS, double averageFPS); + + signals: + void hidden(); + void imageChanged(std::unique_ptr &frame); + + private: + bool processStream; + int streamWidth, streamHeight; + bool colorFrame, isRecording; + QIcon recordIcon, stopIcon; + ISD::CCD *currentCCD; + + // For Canon DSLRs + INDI::Property *eoszoom {nullptr}, *eoszoomposition {nullptr}; + RecordOptions *options; };