[libcamera-devel,v2,4/7] qcam: Introduce a toolbar and camera switching

Message ID 20200214001810.19302-5-kieran.bingham@ideasonboard.com
State Accepted
Headers show
Series
  • qcam: Provide an initial toolbar
Related show

Commit Message

Kieran Bingham Feb. 14, 2020, 12:18 a.m. UTC
Implement a quit button, and a list of cameras.

Selecting a different camera from the Toolbar will stop the current
stream, and start streaming the chosen camera device if it can be
acquired.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

---
v2:

 - Add name to toolbar
 - Rename setCamera to switchCamera
 - Disable right click context menu on toolbar.
 - Utilise a combo box for camera selections
 - Squash in "qcam: Expose quit method for MainWindow"

 src/qcam/main_window.cpp | 64 ++++++++++++++++++++++++++++++++++++++--
 src/qcam/main_window.h   |  5 ++++
 2 files changed, 67 insertions(+), 2 deletions(-)

Comments

Laurent Pinchart Feb. 14, 2020, 12:27 a.m. UTC | #1
Hi Kieran,

Thank you for the patch.

On Fri, Feb 14, 2020 at 12:18:07AM +0000, Kieran Bingham wrote:
> Implement a quit button, and a list of cameras.
> 
> Selecting a different camera from the Toolbar will stop the current
> stream, and start streaming the chosen camera device if it can be
> acquired.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> ---
> v2:
> 
>  - Add name to toolbar
>  - Rename setCamera to switchCamera
>  - Disable right click context menu on toolbar.
>  - Utilise a combo box for camera selections
>  - Squash in "qcam: Expose quit method for MainWindow"
> 
>  src/qcam/main_window.cpp | 64 ++++++++++++++++++++++++++++++++++++++--
>  src/qcam/main_window.h   |  5 ++++
>  2 files changed, 67 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
> index 2ed84cacf655..0e9e717b7e1a 100644
> --- a/src/qcam/main_window.cpp
> +++ b/src/qcam/main_window.cpp
> @@ -10,9 +10,12 @@
>  #include <string>
>  #include <sys/mman.h>
>  
> +#include <QComboBox>
>  #include <QCoreApplication>
>  #include <QInputDialog>
>  #include <QTimer>
> +#include <QToolBar>
> +#include <QToolButton>
>  
>  #include <libcamera/camera_manager.h>
>  #include <libcamera/version.h>
> @@ -27,6 +30,8 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
>  {
>  	int ret;
>  
> +	createToolbars();
> +
>  	title_ = "QCam " + QString::fromStdString(CameraManager::version());
>  	setWindowTitle(title_);
>  	connect(&titleTimer_, SIGNAL(timeout()), this, SLOT(updateTitle()));
> @@ -40,8 +45,7 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
>  		ret = startCapture();
>  
>  	if (ret < 0)
> -		QTimer::singleShot(0, QCoreApplication::instance(),
> -				   &QCoreApplication::quit);
> +		quit();
>  }
>  
>  MainWindow::~MainWindow()
> @@ -53,6 +57,39 @@ MainWindow::~MainWindow()
>  	}
>  }
>  
> +int MainWindow::createToolbars()
> +{
> +	QAction *action;
> +
> +	toolbar_ = addToolBar("Main");
> +
> +	/* Disable right click context menu */

I know we need to update checkstyle.py for this...

> +	toolbar_->setContextMenuPolicy(Qt::PreventContextMenu);
> +
> +	action = toolbar_->addAction("Quit");
> +	connect(action, &QAction::triggered, this, &MainWindow::quit);
> +
> +	/* Camera selection */

And here too.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +	QComboBox *cameraCombo = new QComboBox();
> +	connect(cameraCombo, QOverload<int>::of(&QComboBox::activated),
> +		this, &MainWindow::switchCamera);
> +
> +	for (const std::shared_ptr<Camera> &cam : cm_->cameras())
> +		cameraCombo->addItem(QString::fromStdString(cam->name()));
> +
> +	toolbar_->addWidget(cameraCombo);
> +
> +	toolbar_->addSeparator();
> +
> +	return 0;
> +}
> +
> +void MainWindow::quit()
> +{
> +	QTimer::singleShot(0, QCoreApplication::instance(),
> +			   &QCoreApplication::quit);
> +}
> +
>  void MainWindow::updateTitle()
>  {
>  	unsigned int duration = frameRateInterval_.elapsed();
> @@ -66,6 +103,29 @@ void MainWindow::updateTitle()
>  	setWindowTitle(title_ + " : " + QString::number(fps, 'f', 2) + " fps");
>  }
>  
> +void MainWindow::switchCamera(int index)
> +{
> +	const auto &cameras = cm_->cameras();
> +	if (static_cast<unsigned int>(index) >= cameras.size())
> +		return;
> +
> +	const std::shared_ptr<Camera> &cam = cameras[index];
> +
> +	if (cam->acquire()) {
> +		std::cout << "Failed to acquire camera " << cam->name() << std::endl;
> +		return;
> +	}
> +
> +	std::cout << "Switching to camera " << cam->name() << std::endl;
> +
> +	stopCapture();
> +
> +	camera_->release();
> +	camera_ = cam;
> +
> +	startCapture();
> +}
> +
>  std::string MainWindow::chooseCamera()
>  {
>  	QStringList cameras;
> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
> index d19cda16e36b..12af103f87d0 100644
> --- a/src/qcam/main_window.h
> +++ b/src/qcam/main_window.h
> @@ -41,9 +41,13 @@ public:
>  	~MainWindow();
>  
>  private Q_SLOTS:
> +	void quit();
>  	void updateTitle();
>  
> +	void switchCamera(int index);
> +
>  private:
> +	int createToolbars();
>  	std::string chooseCamera();
>  	int openCamera();
>  
> @@ -71,6 +75,7 @@ private:
>  	uint32_t previousFrames_;
>  	uint32_t framesCaptured_;
>  
> +	QToolBar *toolbar_;
>  	ViewFinder *viewfinder_;
>  	std::map<int, std::pair<void *, unsigned int>> mappedBuffers_;
>  };
Kieran Bingham Feb. 14, 2020, 8:31 a.m. UTC | #2
Hi Laurent,

On 14/02/2020 00:27, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Fri, Feb 14, 2020 at 12:18:07AM +0000, Kieran Bingham wrote:
>> Implement a quit button, and a list of cameras.
>>
>> Selecting a different camera from the Toolbar will stop the current
>> stream, and start streaming the chosen camera device if it can be
>> acquired.
>>
>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
>>
>> ---
>> v2:
>>
>>  - Add name to toolbar
>>  - Rename setCamera to switchCamera
>>  - Disable right click context menu on toolbar.
>>  - Utilise a combo box for camera selections
>>  - Squash in "qcam: Expose quit method for MainWindow"
>>
>>  src/qcam/main_window.cpp | 64 ++++++++++++++++++++++++++++++++++++++--
>>  src/qcam/main_window.h   |  5 ++++
>>  2 files changed, 67 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
>> index 2ed84cacf655..0e9e717b7e1a 100644
>> --- a/src/qcam/main_window.cpp
>> +++ b/src/qcam/main_window.cpp
>> @@ -10,9 +10,12 @@
>>  #include <string>
>>  #include <sys/mman.h>
>>  
>> +#include <QComboBox>
>>  #include <QCoreApplication>
>>  #include <QInputDialog>
>>  #include <QTimer>
>> +#include <QToolBar>
>> +#include <QToolButton>
>>  
>>  #include <libcamera/camera_manager.h>
>>  #include <libcamera/version.h>
>> @@ -27,6 +30,8 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
>>  {
>>  	int ret;
>>  
>> +	createToolbars();
>> +
>>  	title_ = "QCam " + QString::fromStdString(CameraManager::version());
>>  	setWindowTitle(title_);
>>  	connect(&titleTimer_, SIGNAL(timeout()), this, SLOT(updateTitle()));
>> @@ -40,8 +45,7 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
>>  		ret = startCapture();
>>  
>>  	if (ret < 0)
>> -		QTimer::singleShot(0, QCoreApplication::instance(),
>> -				   &QCoreApplication::quit);
>> +		quit();
>>  }
>>  
>>  MainWindow::~MainWindow()
>> @@ -53,6 +57,39 @@ MainWindow::~MainWindow()
>>  	}
>>  }
>>  
>> +int MainWindow::createToolbars()
>> +{
>> +	QAction *action;
>> +
>> +	toolbar_ = addToolBar("Main");
>> +
>> +	/* Disable right click context menu */
> 
> I know we need to update checkstyle.py for this...

See, I still think a period is really quite redundant there :-)

Fixups applied all the same.


>> +	toolbar_->setContextMenuPolicy(Qt::PreventContextMenu);
>> +
>> +	action = toolbar_->addAction("Quit");
>> +	connect(action, &QAction::triggered, this, &MainWindow::quit);
>> +
>> +	/* Camera selection */
> 
> And here too.
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
>> +	QComboBox *cameraCombo = new QComboBox();
>> +	connect(cameraCombo, QOverload<int>::of(&QComboBox::activated),
>> +		this, &MainWindow::switchCamera);
>> +
>> +	for (const std::shared_ptr<Camera> &cam : cm_->cameras())
>> +		cameraCombo->addItem(QString::fromStdString(cam->name()));
>> +
>> +	toolbar_->addWidget(cameraCombo);
>> +
>> +	toolbar_->addSeparator();
>> +
>> +	return 0;
>> +}
>> +
>> +void MainWindow::quit()
>> +{
>> +	QTimer::singleShot(0, QCoreApplication::instance(),
>> +			   &QCoreApplication::quit);
>> +}
>> +
>>  void MainWindow::updateTitle()
>>  {
>>  	unsigned int duration = frameRateInterval_.elapsed();
>> @@ -66,6 +103,29 @@ void MainWindow::updateTitle()
>>  	setWindowTitle(title_ + " : " + QString::number(fps, 'f', 2) + " fps");
>>  }
>>  
>> +void MainWindow::switchCamera(int index)
>> +{
>> +	const auto &cameras = cm_->cameras();
>> +	if (static_cast<unsigned int>(index) >= cameras.size())
>> +		return;
>> +
>> +	const std::shared_ptr<Camera> &cam = cameras[index];
>> +
>> +	if (cam->acquire()) {
>> +		std::cout << "Failed to acquire camera " << cam->name() << std::endl;
>> +		return;
>> +	}
>> +
>> +	std::cout << "Switching to camera " << cam->name() << std::endl;
>> +
>> +	stopCapture();
>> +
>> +	camera_->release();
>> +	camera_ = cam;
>> +
>> +	startCapture();
>> +}
>> +
>>  std::string MainWindow::chooseCamera()
>>  {
>>  	QStringList cameras;
>> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
>> index d19cda16e36b..12af103f87d0 100644
>> --- a/src/qcam/main_window.h
>> +++ b/src/qcam/main_window.h
>> @@ -41,9 +41,13 @@ public:
>>  	~MainWindow();
>>  
>>  private Q_SLOTS:
>> +	void quit();
>>  	void updateTitle();
>>  
>> +	void switchCamera(int index);
>> +
>>  private:
>> +	int createToolbars();
>>  	std::string chooseCamera();
>>  	int openCamera();
>>  
>> @@ -71,6 +75,7 @@ private:
>>  	uint32_t previousFrames_;
>>  	uint32_t framesCaptured_;
>>  
>> +	QToolBar *toolbar_;
>>  	ViewFinder *viewfinder_;
>>  	std::map<int, std::pair<void *, unsigned int>> mappedBuffers_;
>>  };
>

Patch

diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index 2ed84cacf655..0e9e717b7e1a 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -10,9 +10,12 @@ 
 #include <string>
 #include <sys/mman.h>
 
+#include <QComboBox>
 #include <QCoreApplication>
 #include <QInputDialog>
 #include <QTimer>
+#include <QToolBar>
+#include <QToolButton>
 
 #include <libcamera/camera_manager.h>
 #include <libcamera/version.h>
@@ -27,6 +30,8 @@  MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
 {
 	int ret;
 
+	createToolbars();
+
 	title_ = "QCam " + QString::fromStdString(CameraManager::version());
 	setWindowTitle(title_);
 	connect(&titleTimer_, SIGNAL(timeout()), this, SLOT(updateTitle()));
@@ -40,8 +45,7 @@  MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
 		ret = startCapture();
 
 	if (ret < 0)
-		QTimer::singleShot(0, QCoreApplication::instance(),
-				   &QCoreApplication::quit);
+		quit();
 }
 
 MainWindow::~MainWindow()
@@ -53,6 +57,39 @@  MainWindow::~MainWindow()
 	}
 }
 
+int MainWindow::createToolbars()
+{
+	QAction *action;
+
+	toolbar_ = addToolBar("Main");
+
+	/* Disable right click context menu */
+	toolbar_->setContextMenuPolicy(Qt::PreventContextMenu);
+
+	action = toolbar_->addAction("Quit");
+	connect(action, &QAction::triggered, this, &MainWindow::quit);
+
+	/* Camera selection */
+	QComboBox *cameraCombo = new QComboBox();
+	connect(cameraCombo, QOverload<int>::of(&QComboBox::activated),
+		this, &MainWindow::switchCamera);
+
+	for (const std::shared_ptr<Camera> &cam : cm_->cameras())
+		cameraCombo->addItem(QString::fromStdString(cam->name()));
+
+	toolbar_->addWidget(cameraCombo);
+
+	toolbar_->addSeparator();
+
+	return 0;
+}
+
+void MainWindow::quit()
+{
+	QTimer::singleShot(0, QCoreApplication::instance(),
+			   &QCoreApplication::quit);
+}
+
 void MainWindow::updateTitle()
 {
 	unsigned int duration = frameRateInterval_.elapsed();
@@ -66,6 +103,29 @@  void MainWindow::updateTitle()
 	setWindowTitle(title_ + " : " + QString::number(fps, 'f', 2) + " fps");
 }
 
+void MainWindow::switchCamera(int index)
+{
+	const auto &cameras = cm_->cameras();
+	if (static_cast<unsigned int>(index) >= cameras.size())
+		return;
+
+	const std::shared_ptr<Camera> &cam = cameras[index];
+
+	if (cam->acquire()) {
+		std::cout << "Failed to acquire camera " << cam->name() << std::endl;
+		return;
+	}
+
+	std::cout << "Switching to camera " << cam->name() << std::endl;
+
+	stopCapture();
+
+	camera_->release();
+	camera_ = cam;
+
+	startCapture();
+}
+
 std::string MainWindow::chooseCamera()
 {
 	QStringList cameras;
diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
index d19cda16e36b..12af103f87d0 100644
--- a/src/qcam/main_window.h
+++ b/src/qcam/main_window.h
@@ -41,9 +41,13 @@  public:
 	~MainWindow();
 
 private Q_SLOTS:
+	void quit();
 	void updateTitle();
 
+	void switchCamera(int index);
+
 private:
+	int createToolbars();
 	std::string chooseCamera();
 	int openCamera();
 
@@ -71,6 +75,7 @@  private:
 	uint32_t previousFrames_;
 	uint32_t framesCaptured_;
 
+	QToolBar *toolbar_;
 	ViewFinder *viewfinder_;
 	std::map<int, std::pair<void *, unsigned int>> mappedBuffers_;
 };