diff options
Diffstat (limited to 'plugingui')
| -rw-r--r-- | plugingui/Makefile.am | 2 | ||||
| -rw-r--r-- | plugingui/checkbox.cc | 13 | ||||
| -rw-r--r-- | plugingui/powerwidget.cc | 332 | ||||
| -rw-r--r-- | plugingui/powerwidget.h | 97 | 
4 files changed, 437 insertions, 7 deletions
| diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am index 10bf23a..219b450 100644 --- a/plugingui/Makefile.am +++ b/plugingui/Makefile.am @@ -92,6 +92,7 @@ nodist_libdggui_la_SOURCES = \  	pixelbuffer.cc \  	pluginconfig.cc \  	powerbutton.cc \ +	powerwidget.cc \  	progressbar.cc \  	resamplingframecontent.cc \  	resource.cc \ @@ -232,6 +233,7 @@ EXTRA_DIST = \  	pixelbuffer.h \  	pluginconfig.h \  	powerbutton.h \ +	powerwidget.h \  	progressbar.h \  	resamplingframecontent.h \  	resource.h \ diff --git a/plugingui/checkbox.cc b/plugingui/checkbox.cc index 1893f59..f3601bd 100644 --- a/plugingui/checkbox.cc +++ b/plugingui/checkbox.cc @@ -32,19 +32,18 @@ namespace GUI  {  CheckBox::CheckBox(Widget* parent) -    : Toggle(parent) -    , bg_on(getImageCache(), ":resources/switch_back_on.png") -    , bg_off(getImageCache(), ":resources/switch_back_off.png") -    , knob(getImageCache(), ":resources/switch_front.png") +	: Toggle(parent) +	, bg_on(getImageCache(), ":resources/switch_back_on.png") +	, bg_off(getImageCache(), ":resources/switch_back_off.png") +	, knob(getImageCache(), ":resources/switch_front.png")  {  }  void CheckBox::repaintEvent(RepaintEvent* repaintEvent)  {  	Painter p(*this); - -	p.drawImage( -	    0, (knob.height() - bg_on.height()) / 2, state ? bg_on : bg_off); +	p.clear(); +	p.drawImage(0, (knob.height() - bg_on.height()) / 2, state ? bg_on : bg_off);  	if(clicked)  	{ diff --git a/plugingui/powerwidget.cc b/plugingui/powerwidget.cc new file mode 100644 index 0000000..02e7253 --- /dev/null +++ b/plugingui/powerwidget.cc @@ -0,0 +1,332 @@ +/* -*- Mode: c++ -*- */ +/*************************************************************************** + *            powerwidget.cc + * + *  Fri Apr 24 17:30:45 CEST 2020 + *  Copyright 2020 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  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 "powerwidget.h" + +#include "painter.h" + +#include <notifier.h> +#include <settings.h> +#include <colour.h> +#include <powermap.h> + +#include <hugin.hpp> +#include <cmath> + +PowerWidget::PowerWidget(GUI::Widget* parent, +                         Settings& settings, +                         SettingsNotifier& settings_notifier) +	: GUI::Widget(parent) +	, canvas(this, settings, settings_notifier) +	, settings(settings) +{ +	canvas.move(7, 7); + +	CONNECT(&shelf_checkbox, stateChangedNotifier, this, &PowerWidget::chk_shelf); + +	shelf_label.setText("Shelf"); +	shelf_label.setAlignment(GUI::TextAlignment::center); +	shelf_label.resize(59, 16); +	shelf_checkbox.resize(59, 40); + +	CONNECT(&settings_notifier, powermap_shelf, &shelf_checkbox, +	        &GUI::CheckBox::setChecked); +} + +void PowerWidget::chk_shelf(bool v) +{ +	settings.powermap_shelf.store(v); +} + +void PowerWidget::repaintEvent(GUI::RepaintEvent *repaintEvent) +{ +	GUI::Painter p(*this); +	box.setSize(width() - 59 - 64, height()); +	p.drawImage(0, 0, box); +} + +void PowerWidget::resize(std::size_t width, std::size_t height) +{ +	Widget::resize(width, height); +	if(width < (14 + 59 + 64) || height < 14) +	{ +		canvas.resize(1, 1); +		return; +	} +	canvas.resize(width - 14 - 59 - 64, height - 14); + +	shelf_label.move(width - 59 + 5 - 32 , 0); +	shelf_checkbox.move(width - 59 + 5 - 32, 16); +} + +PowerWidget::Canvas::Canvas(GUI::Widget* parent, +                            Settings& settings, +                            SettingsNotifier& settings_notifier) +	: GUI::Widget(parent) +	, settings_notifier(settings_notifier) +	, settings(settings) +{ +	CONNECT(this, settings_notifier.enable_powermap, +	        this, &PowerWidget::Canvas::parameterChangedBool); +	CONNECT(this, settings_notifier.powermap_fixed0_x, +	        this, &PowerWidget::Canvas::parameterChangedFloat); +	CONNECT(this, settings_notifier.powermap_fixed0_y, +	        this, &PowerWidget::Canvas::parameterChangedFloat); +	CONNECT(this, settings_notifier.powermap_fixed1_x, +	        this, &PowerWidget::Canvas::parameterChangedFloat); +	CONNECT(this, settings_notifier.powermap_fixed1_y, +	        this, &PowerWidget::Canvas::parameterChangedFloat); +	CONNECT(this, settings_notifier.powermap_fixed2_x, +	        this, &PowerWidget::Canvas::parameterChangedFloat); +	CONNECT(this, settings_notifier.powermap_fixed2_y, +	        this, &PowerWidget::Canvas::parameterChangedFloat); +	CONNECT(this, settings_notifier.powermap_shelf, +	        this, &PowerWidget::Canvas::parameterChangedBool); +	CONNECT(this, settings_notifier.powermap_input, +	        this, &PowerWidget::Canvas::parameterChangedFloat); +	CONNECT(this, settings_notifier.powermap_output, +	        this, &PowerWidget::Canvas::parameterChangedFloat); + +	parameterChangedFloat(0); +} + +void PowerWidget::Canvas::repaintEvent(GUI::RepaintEvent *repaintEvent) +{ +	if(width() < 1 || height() < 1) +	{ +		return; +	} + +	const float x0 = brd; +	const float y0 = brd; +	const float width0 = (int)width() - 2 * brd; +	const float height0 = (int)height() - 2 * brd; + +	GUI::Painter p(*this); + +	p.clear(); + +	p.setColour(GUI::Colour(1.0f, 1.0f, 1.0f, 0.2f)); +	p.drawRectangle(x0, y0 + height0, x0 + width0, y0); + +	if(enabled) +	{ +		// draw 1:1 line in grey in the background to indicate where 1:1 is +		p.setColour(GUI::Colour(0.5)); +		p.drawLine(x0, y0 + height0, x0 + width0, y0); +	} + +	if(enabled) +	{ +		// enabled green +		p.setColour(GUI::Colour(0.0f, 1.0f, 0.0f, 1.0f)); +	} +	else +	{ +		// disabled grey +		p.setColour(GUI::Colour(0.5f)); +	} + +	// Draw very short line segments across the region +	std::pair<int, int> old{}; +	for(std::size_t x = 0; x < width0; ++x) +	{ +		int y = power_map.map((float)x / width0) * height0; +		if(x > 0) +		{ +			p.drawLine(x0 + old.first, y0 + old.second, x0 + x, y0 + height0 - y); +		} +		old = { x, height0 - y }; +	} + +	int x = width0; +	int y = power_map.map((float)x / width0) * height0; +	p.drawLine(x0 + old.first, y0 + old.second, x0 + x, y0 + height0 - y); +	old = { x, height0 - y }; + +	if(!enabled) +	{ +		// draw 1:1 line in green in the foreground +		p.setColour(GUI::Colour(0.0f, 1.0f, 0.0f, 1.0f)); +		p.drawLine(x0, y0 + height0, x0 + width0, y0); +	} + +	// draw the input/output of the last hit +	if(settings.powermap_input.load() != -1 && settings.powermap_output.load() != -1) +	{ +		p.setColour(GUI::Colour(.8f, 0.0f, .2f, .5f)); +		p.drawLine(x0 + settings.powermap_input.load()*width0, y0 + height0, +				   x0 + settings.powermap_input.load()*width0, y0); +		p.drawLine(x0, y0 + height0 - settings.powermap_output.load()*height0, +				   x0 + width0, y0 + height0 - settings.powermap_output.load()*height0); +	} + +	// draw the fixed nodes of the spline +	float rad = radius * width(); +	p.setColour(GUI::Colour{0.0f, 1.0f, 0.0f, 0.7f}); +	p.drawFilledCircle(x0 + std::round(settings.powermap_fixed0_x.load() * width0), +	                   y0 + height0 - std::round(settings.powermap_fixed0_y.load() * height0), rad); +	p.drawCircle(x0 + std::round(power_map.getFixed0().in * width0), +	             y0 + height0 - std::round(power_map.getFixed0().out * height0), rad + 1); + +	p.setColour(GUI::Colour{1.0f, 1.0f, 0.0f, 0.7f}); +	p.drawFilledCircle(x0 + std::round(settings.powermap_fixed1_x.load() * width0), +	                   y0 + height0 - std::round(settings.powermap_fixed1_y.load() * height0), rad); +	p.drawCircle(x0 + std::round(power_map.getFixed1().in * width0), +	             y0 + height0 - std::round(power_map.getFixed1().out * height0), rad + 1); + +	p.setColour(GUI::Colour{1.0f, 0.0f, 0.0f, 0.7f}); +	p.drawFilledCircle(x0 + std::round(settings.powermap_fixed2_x.load() * width0), +	                   y0 + height0 - std::round(settings.powermap_fixed2_y.load() * height0), rad); +	p.drawCircle(x0 + std::round(power_map.getFixed2().in * width0), +	             y0 + height0 - std::round(power_map.getFixed2().out * height0), rad + 1); + +	p.setColour(GUI::Colour(1.0f, 1.0f, 1.0f, 0.2f)); +	p.drawText(width() / 2 - (font.textWidth("in") / 2), height() - 8, font, "in"); +	p.drawText(8, height() / 2 - (font.textWidth("out") / 2), font, "out", false, true); +} + +void PowerWidget::Canvas::buttonEvent(GUI::ButtonEvent* buttonEvent) +{ +	const float x0 = brd; +	const float y0 = brd; +	const float width0 = (int)width() - 2 * brd; +	const float height0 = (int)height() - 2 * brd; + +	float mx0 = (float)(buttonEvent->x - x0) / width0; +	float my0 = (float)(((int)height() - buttonEvent->y) - y0) / height0; + +	float radius_x = radius * 2; +	float radius_y = radius * width0 / height0 * 2; + +	switch(buttonEvent->direction) +	{ +	case GUI::Direction::up: +		in_point = -1; +		break; +	case GUI::Direction::down: +		if(std::abs(mx0 - settings.powermap_fixed0_x.load()) < radius_x && +		   std::abs(my0 - settings.powermap_fixed0_y.load()) < radius_y) +		{ +			in_point = 0; +		} + +		if(std::abs(mx0 - settings.powermap_fixed1_x.load()) < radius_x && +		   std::abs(my0 - settings.powermap_fixed1_y.load()) < radius_y) +		{ +			in_point = 1; +		} + +		if(std::abs(mx0 - settings.powermap_fixed2_x.load()) < radius_x && +		   std::abs(my0 - settings.powermap_fixed2_y.load()) < radius_y) +		{ +			in_point = 2; +		} +		break; +	} +} + +namespace +{ +float clamp(float val, float min, float max) +{ +	return std::max(min, std::min(max, val)); +} +} + +void PowerWidget::Canvas::mouseMoveEvent(GUI::MouseMoveEvent* mouseMoveEvent) +{ +	const float x0 = brd; +	const float y0 = brd; +	const float width0 = (int)width() - 2 * brd; +	const float height0 = (int)height() - 2 * brd; + +	float mx0 = (float)(mouseMoveEvent->x - x0) / width0; +	float my0 = (float)(((int)height() - mouseMoveEvent->y) - y0) / height0; + +	switch(in_point) +	{ +	case 0: +		settings.powermap_fixed0_x.store(clamp(mx0, 0, 1)); +		settings.powermap_fixed0_y.store(clamp(my0, 0, 1)); +		redraw(); +		break; +	case 1: +		settings.powermap_fixed1_x.store(clamp(mx0, 0, 1)); +		settings.powermap_fixed1_y.store(clamp(my0, 0, 1)); +		redraw(); +		break; +	case 2: +		settings.powermap_fixed2_x.store(clamp(mx0, 0, 1)); +		settings.powermap_fixed2_y.store(clamp(my0, 0, 1)); +		redraw(); +		break; +	default: +		break; +	} +/* +	switch(in_point) +	{ +	case 0: +		settings.fixed0_x.store(clamp((float)mouseMoveEvent->x / width())); +		settings.fixed0_y.store(1.0f - clamp((float)mouseMoveEvent->y / height())); +		redraw(); +		break; +	case 1: +		settings.fixed1_x.store(clamp((float)mouseMoveEvent->x / width())); +		settings.fixed1_y.store(1.0f - clamp((float)mouseMoveEvent->y / height())); +		redraw(); +		break; +	case 2: +		settings.fixed2_x.store(clamp((float)mouseMoveEvent->x / width())); +		settings.fixed2_y.store(1.0f - clamp((float)mouseMoveEvent->y / height())); +		redraw(); +		break; +	default: +		break; +	} +*/ +} + +void PowerWidget::Canvas::mouseLeaveEvent() +{ +	//in_point = -1; +} + +void PowerWidget::Canvas::parameterChangedFloat(float) +{ +	power_map.setFixed0({settings.powermap_fixed0_x.load(), settings.powermap_fixed0_y.load()}); +	power_map.setFixed1({settings.powermap_fixed1_x.load(), settings.powermap_fixed1_y.load()}); +	power_map.setFixed2({settings.powermap_fixed2_x.load(), settings.powermap_fixed2_y.load()}); +	power_map.setShelf(settings.powermap_shelf.load()); +	enabled = settings.enable_powermap.load(); +	redraw(); +} + +void PowerWidget::Canvas::parameterChangedBool(bool) +{ +	parameterChangedFloat(0); +} diff --git a/plugingui/powerwidget.h b/plugingui/powerwidget.h new file mode 100644 index 0000000..c5c6665 --- /dev/null +++ b/plugingui/powerwidget.h @@ -0,0 +1,97 @@ +/* -*- Mode: c++ -*- */ +/*************************************************************************** + *            powerwidget.h + * + *  Fri Apr 24 17:30:45 CEST 2020 + *  Copyright 2020 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  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. + */ +#pragma once + +#include <widget.h> +#include <texturedbox.h> +#include <texture.h> +#include <knob.h> +#include <checkbox.h> +#include <label.h> +#include <font.h> +#include <powermap.h> + +struct Settings; +class SettingsNotifier; + +class PowerWidget +	: public GUI::Widget +{ +public: +	PowerWidget(GUI::Widget* parent, +	            Settings& settings, +	            SettingsNotifier& settings_notifier); + +	// From Widget: +	virtual void repaintEvent(GUI::RepaintEvent *repaintEvent) override; +	virtual void resize(std::size_t width, std::size_t height) override; + +private: +	GUI::TexturedBox box{getImageCache(), ":resources/widget.png", +			0, 0, // atlas offset (x, y) +			7, 1, 7, // dx1, dx2, dx3 +			7, 63, 7}; // dy1, dy2, dy3 + +	class Canvas +		: public GUI::Widget +	{ +	public: +		Canvas(GUI::Widget* parent, Settings& settings, +		       SettingsNotifier& settings_notifier); + +		// From Widget: +		virtual bool catchMouse() override { return true; } +		virtual void repaintEvent(GUI::RepaintEvent *repaintEvent) override; +		virtual void buttonEvent(GUI::ButtonEvent* buttonEvent) override; +		virtual void mouseMoveEvent(GUI::MouseMoveEvent* mouseMoveEvent) override; +		virtual void mouseLeaveEvent() override; + +	private: +		Powermap power_map; + +		void parameterChangedFloat(float); +		void parameterChangedBool(bool); + +		SettingsNotifier& settings_notifier; +		Settings& settings; + +		bool enabled{true}; + +		int in_point{-1}; +		const float radius = 0.02f; +		const float brd = 6.0f; +		GUI::Font font{":resources/fontemboss.png"}; +	}; + +	void chk_shelf(bool v); + +	Canvas canvas; +	GUI::Label shelf_label{this}; +	GUI::CheckBox shelf_checkbox{this}; + +	Settings& settings; +}; | 
