From 13ab76b2d587a786112a35b5bcccf5e264700f9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Nusser?= <andre.nusser@googlemail.com>
Date: Wed, 24 May 2017 16:21:12 +0200
Subject: Add frame in the GUI for bleed control.

---
 plugin/Makefile.mingw32.in             |   1 +
 plugin/drumgizmo_plugin.h              |   2 +-
 plugingui/Makefile.am                  |   1 +
 plugingui/Makefile.mingw32             |   1 +
 plugingui/bleedcontrolframecontent.cc  | 104 +++++++++++++++++++++++++++++++++
 plugingui/bleedcontrolframecontent.h   |  69 ++++++++++++++++++++++
 plugingui/diskstreamingframecontent.cc |  12 ++--
 plugingui/diskstreamingframecontent.h  |   2 +-
 plugingui/layout.cc                    |  29 +++++++++
 plugingui/layout.h                     |   3 +
 plugingui/maintab.cc                   |  59 +++++++++----------
 plugingui/maintab.h                    |   8 ++-
 plugingui/testmain.cc                  |   3 +-
 13 files changed, 251 insertions(+), 43 deletions(-)
 create mode 100644 plugingui/bleedcontrolframecontent.cc
 create mode 100644 plugingui/bleedcontrolframecontent.h

diff --git a/plugin/Makefile.mingw32.in b/plugin/Makefile.mingw32.in
index 77f43e1..b22febd 100644
--- a/plugin/Makefile.mingw32.in
+++ b/plugin/Makefile.mingw32.in
@@ -47,6 +47,7 @@ DG_CFLAGS = -I@top_srcdir@ -I@top_srcdir@/include -I@top_srcdir@/src \
 
 GUI_SRC = \
 	@top_srcdir@/plugingui/abouttab.cc \
+	@top_srcdir@/plugingui/bleedcontrolframecontent.cc \
 	@top_srcdir@/plugingui/button.cc \
 	@top_srcdir@/plugingui/button_base.cc \
 	@top_srcdir@/plugingui/checkbox.cc \
diff --git a/plugin/drumgizmo_plugin.h b/plugin/drumgizmo_plugin.h
index 2a77f07..e585c45 100644
--- a/plugin/drumgizmo_plugin.h
+++ b/plugin/drumgizmo_plugin.h
@@ -208,5 +208,5 @@ private:
 	bool inline_image_first_draw{true};
 
 	static constexpr std::size_t width{750};
-	static constexpr std::size_t height{385};
+	static constexpr std::size_t height{466};
 };
diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am
index dd36783..c8004b0 100644
--- a/plugingui/Makefile.am
+++ b/plugingui/Makefile.am
@@ -48,6 +48,7 @@ libdggui_la_LIBADD = \
 # If you add a file here, remember to add it to plugin/Makefile.mingw32.in
 nodist_libdggui_la_SOURCES = \
 	abouttab.cc \
+	bleedcontrolframecontent.cc \
 	button.cc \
 	button_base.cc \
 	checkbox.cc \
diff --git a/plugingui/Makefile.mingw32 b/plugingui/Makefile.mingw32
index 39ff2d0..597ecd9 100644
--- a/plugingui/Makefile.mingw32
+++ b/plugingui/Makefile.mingw32
@@ -43,6 +43,7 @@ GUI_SRC = \
 	statusframecontent.cc \
 	humanizerframecontent.cc \
 	diskstreamingframecontent.cc \
+	bleedcontrolframecontent.cc \
 	maintab.cc \
 	frame.cc \
 	knob.cc \
diff --git a/plugingui/bleedcontrolframecontent.cc b/plugingui/bleedcontrolframecontent.cc
new file mode 100644
index 0000000..65c0f7c
--- /dev/null
+++ b/plugingui/bleedcontrolframecontent.cc
@@ -0,0 +1,104 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ *            bleedcontrolframecontent.cc
+ *
+ *  Wed May 24 14:40:16 CEST 2017
+ *  Copyright 2017 André Nusser
+ *  andre.nusser@googlemail.com
+ ****************************************************************************/
+
+/*
+ *  This file is part of DrumGizmo.
+ *
+ *  DrumGizmo is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  DrumGizmo 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with DrumGizmo; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#include "bleedcontrolframecontent.h"
+
+#include <settings.h>
+
+#include <limits>
+
+namespace GUI
+{
+
+BleedcontrolframeContent::BleedcontrolframeContent(Widget* parent,
+                                                   Settings& settings,
+                                                   SettingsNotifier& settings_notifier)
+	: Widget(parent)
+	, slider_width{250}
+	, settings(settings)
+	, settings_notifier(settings_notifier)
+{
+	label_text.setText("Amount of Microphone Bleed:");
+	label_text.setAlignment(TextAlignment::center);
+
+	button.setText("Apply");
+	button.setEnabled(false);
+
+	label_value.setText("0 %");
+	label_value.setAlignment(TextAlignment::center);
+
+	// TODO:
+	// connect to settings (see diskstreaming frame)
+}
+
+void BleedcontrolframeContent::resize(std::size_t width, std::size_t height)
+{
+	Widget::resize(width, height);
+
+	int slider_button_gap = 10;
+
+	slider_width = 0.8 * width;
+	button_width = std::max((int)width - slider_width - slider_button_gap, 0);
+
+	label_text.move(0, 0);
+	slider.move(0, 20);
+	button.move(slider_width + slider_button_gap, 10);
+	label_value.move(0, 40);
+
+	label_text.resize(slider_width, 15);
+	slider.resize(slider_width, 15);
+	button.resize(button_width, 30);
+	label_value.resize(slider_width, 15);
+
+	button.setEnabled(false);
+}
+
+void BleedcontrolframeContent::bleedSettingsValueChanged(float value)
+{
+	slider.setValue(value);
+
+	label_value.setText(std::to_string(100 * value) + " %");
+	slider.setColour(Slider::Colour::Blue);
+
+	button.setEnabled(true);
+}
+
+void BleedcontrolframeContent::bleedValueChanged(float value)
+{
+	// TODO: store new value in settings
+}
+
+void BleedcontrolframeContent::reloadClicked()
+{
+	// TODO
+}
+
+void BleedcontrolframeContent::reloaded(float)
+{
+	button.setEnabled(false);
+}
+
+} // GUI::
diff --git a/plugingui/bleedcontrolframecontent.h b/plugingui/bleedcontrolframecontent.h
new file mode 100644
index 0000000..2fefd64
--- /dev/null
+++ b/plugingui/bleedcontrolframecontent.h
@@ -0,0 +1,69 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ *            bleedcontrolframecontent.h
+ *
+ *  Wed May 24 14:40:16 CEST 2017
+ *  Copyright 2017 André Nusser
+ *  andre.nusser@googlemail.com
+ ****************************************************************************/
+
+/*
+ *  This file is part of DrumGizmo.
+ *
+ *  DrumGizmo is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  DrumGizmo 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with DrumGizmo; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+
+#include "button.h"
+#include "label.h"
+#include "slider.h"
+#include "widget.h"
+
+struct Settings;
+class SettingsNotifier;
+
+namespace GUI
+{
+
+class BleedcontrolframeContent : public Widget
+{
+public:
+	BleedcontrolframeContent(Widget* parent,
+	                         Settings& settings,
+	                         SettingsNotifier& settings_notifier);
+
+	// From Widget
+	virtual void resize(std::size_t width, std::size_t height) override;
+
+private:
+	void bleedSettingsValueChanged(float value);
+	void bleedValueChanged(float value);
+	void reloadClicked();
+	void reloaded(float);
+
+	Label label_text{this};
+	Label label_value{this};
+
+	Slider slider{this};
+	Button button{this};
+
+	int slider_width;
+	int button_width;
+
+	Settings& settings;
+	SettingsNotifier& settings_notifier;
+};
+
+} // GUI::
+#pragma once
diff --git a/plugingui/diskstreamingframecontent.cc b/plugingui/diskstreamingframecontent.cc
index 4bd9cad..008aee3 100644
--- a/plugingui/diskstreamingframecontent.cc
+++ b/plugingui/diskstreamingframecontent.cc
@@ -47,8 +47,8 @@ DiskstreamingframeContent::DiskstreamingframeContent(Widget* parent,
 	button.setText("Apply");
 	button.setEnabled(false);
 
-	label_size.setText("0 MB");
-	label_size.setAlignment(TextAlignment::center);
+	label_value.setText("0 MB");
+	label_value.setAlignment(TextAlignment::center);
 
 	CONNECT(this, settings_notifier.disk_cache_upper_limit,
 	        this, &DiskstreamingframeContent::limitSettingsValueChanged);
@@ -81,12 +81,12 @@ void DiskstreamingframeContent::resize(std::size_t width, std::size_t height)
 	label_text.move(0, 0);
 	slider.move(0, 20);
 	button.move(slider_width + slider_button_gap, 10);
-	label_size.move(0, 40);
+	label_value.move(0, 40);
 
 	label_text.resize(slider_width, 15);
 	slider.resize(slider_width, 15);
 	button.resize(button_width, 30);
-	label_size.resize(slider_width, 15);
+	label_value.resize(slider_width, 15);
 
 	button.setEnabled(false);
 }
@@ -98,11 +98,11 @@ void DiskstreamingframeContent::limitSettingsValueChanged(std::size_t value)
 
 	if (new_slider_value < 0.99) {
 		int value_in_mb = value/(1024 * 1024);
-		label_size.setText(std::to_string(value_in_mb) + " MB");
+		label_value.setText(std::to_string(value_in_mb) + " MB");
 		slider.setColour(Slider::Colour::Blue);
 	}
 	else {
-		label_size.setText("Unlimited");
+		label_value.setText("Unlimited");
 		slider.setColour(Slider::Colour::Grey);
 	}
 
diff --git a/plugingui/diskstreamingframecontent.h b/plugingui/diskstreamingframecontent.h
index e404807..eabc6e2 100644
--- a/plugingui/diskstreamingframecontent.h
+++ b/plugingui/diskstreamingframecontent.h
@@ -58,7 +58,7 @@ private:
 	static constexpr std::size_t max_limit = 1024.0 * 1024.0 * 1024.0 * 4.0 - 1;
 
 	Label label_text{this};
-	Label label_size{this};
+	Label label_value{this};
 
 	Slider slider{this};
 	Button button{this};
diff --git a/plugingui/layout.cc b/plugingui/layout.cc
index 1e18c40..da64d1b 100644
--- a/plugingui/layout.cc
+++ b/plugingui/layout.cc
@@ -293,6 +293,35 @@ void GridLayout::setPosition(LayoutItem* item, GridRange const& range)
 	grid_ranges[item] = range;
 }
 
+int GridLayout::lastUsedRow(int column) const
+{
+	int last_row = -1;
+
+	for (auto const& grid_range : grid_ranges) {
+		auto const& range = grid_range.second;
+		if (column >= range.column_begin && column < range.column_end) {
+			last_row = std::max(last_row, range.row_end - 1);
+		}
+	}
+
+	return last_row;
+}
+
+int GridLayout::lastUsedColumn(int row) const
+{
+	int last_column = -1;
+
+	for (auto const& grid_range : grid_ranges) {
+		auto const& range = grid_range.second;
+		if (row >= range.row_begin && row < range.row_end) {
+			last_column = std::max(last_column, range.column_end - 1);
+		}
+	}
+
+	return last_column;
+
+}
+
 auto GridLayout::calculateCellSize() const -> CellSize
 {
 	auto empty_width = (number_of_columns - 1) * spacing;
diff --git a/plugingui/layout.h b/plugingui/layout.h
index 763f616..210c86e 100644
--- a/plugingui/layout.h
+++ b/plugingui/layout.h
@@ -169,6 +169,9 @@ public:
 
 	void setPosition(LayoutItem* item, GridRange const& range);
 
+	int lastUsedRow(int column) const;
+	int lastUsedColumn(int row) const;
+
 protected:
 	std::size_t number_of_columns;
 	std::size_t number_of_rows;
diff --git a/plugingui/maintab.cc b/plugingui/maintab.cc
index f0743a8..8238988 100644
--- a/plugingui/maintab.cc
+++ b/plugingui/maintab.cc
@@ -26,9 +26,13 @@
  */
 #include "maintab.h"
 
+// FIXME:
+#include <iostream>
+
 namespace GUI
 {
 
+// TODO: Reduce boilerplate code in this constructor
 MainTab::MainTab(Widget* parent,
                  Settings& settings,
                  SettingsNotifier& settings_notifier,
@@ -38,6 +42,7 @@ MainTab::MainTab(Widget* parent,
 	, statusframe_content{this, settings_notifier}
 	, humanizerframe_content{this, settings, settings_notifier}
 	, diskstreamingframe_content{this, settings, settings_notifier}
+	, bleedcontrolframe_content{this, settings, settings_notifier}
 	, resamplingframe_content{this, settings_notifier}
 	, settings(settings)
 	, settings_notifier(settings_notifier)
@@ -45,39 +50,12 @@ MainTab::MainTab(Widget* parent,
 	layout.setSpacing(0);
 	layout.setResizeChildren(true);
 
-	layout.addItem(&drumkit_frame);
-	layout.addItem(&status_frame);
-	layout.addItem(&humanizer_frame);
-	layout.addItem(&diskstreaming_frame);
-	layout.addItem(&resampling_frame);
-
-	auto h1 = 20;
-	auto h2 = 20;
-	auto h3 = 13;
-	auto h4 = 11;
-	auto h5 = 14;
-	auto drumkit_range = GridLayout::GridRange{0, 1, 0, h1};
-	auto status_range = GridLayout::GridRange{0, 1, h1, h1 + h2};
-	auto humanizer_range = GridLayout::GridRange{1, 2, 0, h3};
-	auto diskstreaming_range = GridLayout::GridRange{1, 2, h3, h3 + h4};
-	auto resampling_range = GridLayout::GridRange{1, 2, h3 + h4, h3 + h4 + h5};
-	layout.setPosition(&drumkit_frame, drumkit_range);
-	layout.setPosition(&status_frame, status_range);
-	layout.setPosition(&humanizer_frame, humanizer_range);
-	layout.setPosition(&diskstreaming_frame, diskstreaming_range);
-	layout.setPosition(&resampling_frame, resampling_range);
-
-	drumkit_frame.setTitle("Drumkit");
-	status_frame.setTitle("Status");
-	humanizer_frame.setTitle("Humanizer");
-	diskstreaming_frame.setTitle("Disk streaming");
-	resampling_frame.setTitle("Resampling");
-
-	drumkit_frame.setContent(&drumkitframe_content);
-	status_frame.setContent(&statusframe_content);
-	humanizer_frame.setContent(&humanizerframe_content);
-	diskstreaming_frame.setContent(&diskstreamingframe_content);
-	resampling_frame.setContent(&resamplingframe_content);
+	add("Drumkit", drumkit_frame, drumkitframe_content, 20, 0);
+	add("Status", status_frame, statusframe_content, 29, 0);
+	add("Humanizer", humanizer_frame, humanizerframe_content, 13, 1);
+	add("Disk Streaming", diskstreaming_frame, diskstreamingframe_content, 11, 1);
+	add("Bleed Control", bleedcontrol_frame, bleedcontrolframe_content, 11, 1);
+	add("Resampling", resampling_frame, resamplingframe_content, 14, 1);
 
 	humanizer_frame.setOnSwitch(settings.enable_velocity_modifier);
 	resampling_frame.setOnSwitch(settings.enable_resampling);
@@ -112,4 +90,19 @@ void MainTab::resamplingOnChange(bool on)
 	settings.enable_resampling.store(on);
 }
 
+void MainTab::add(std::string const& title, FrameWidget& frame, Widget& content,
+		 std::size_t height, int column)
+{
+	layout.addItem(&frame);
+	frame.setTitle(title);
+	frame.setContent(&content);
+
+	auto grid_start = layout.lastUsedRow(column) + 1;
+	auto range = GridLayout::GridRange{column,
+	                                   column + 1,
+	                                   grid_start,
+	                                   grid_start + int(height)};
+	layout.setPosition(&frame, range);
+}
+
 } // GUI::
diff --git a/plugingui/maintab.h b/plugingui/maintab.h
index ab7e760..3463355 100644
--- a/plugingui/maintab.h
+++ b/plugingui/maintab.h
@@ -33,6 +33,7 @@
 #include "statusframecontent.h"
 #include "humanizerframecontent.h"
 #include "diskstreamingframecontent.h"
+#include "bleedcontrolframecontent.h"
 #include "resamplingframecontent.h"
 
 struct Settings;
@@ -60,20 +61,25 @@ private:
 
 	Image logo{":resources/logo.png"};
 
-	GridLayout layout{this, 2, 40};
+	GridLayout layout{this, 2, 49};
 
 	FrameWidget drumkit_frame{this, false};
 	FrameWidget status_frame{this, false};
 	FrameWidget humanizer_frame{this, true};
 	FrameWidget diskstreaming_frame{this, false};
+	FrameWidget bleedcontrol_frame{this, false};
 	FrameWidget resampling_frame{this, true};
 
 	DrumkitframeContent drumkitframe_content;
 	StatusframeContent statusframe_content;
 	HumanizerframeContent humanizerframe_content;
 	DiskstreamingframeContent diskstreamingframe_content;
+	BleedcontrolframeContent bleedcontrolframe_content;
 	ResamplingframeContent resamplingframe_content;
 
+	void add(std::string const& title, FrameWidget& frame, Widget& content,
+	         std::size_t height, int column);
+
 	Settings& settings;
 	SettingsNotifier& settings_notifier;
 };
diff --git a/plugingui/testmain.cc b/plugingui/testmain.cc
index 5231205..07e5f8d 100644
--- a/plugingui/testmain.cc
+++ b/plugingui/testmain.cc
@@ -48,7 +48,8 @@ int main()
 	parent.show();
 	main_window.show();
 
-	parent.resize(750, 400);
+	// TODO: automatically use drumgizmo_plugin.h size here
+	parent.resize(750, 466);
 
 	while(true)
 	{
-- 
cgit v1.2.3