1 /* B.Oops
2  * Glitch effect sequencer LV2 plugin
3  *
4  * Copyright (C) 2020 by Sven Jähnichen
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef OPTIONBANGER_HPP_
21 #define OPTIONBANGER_HPP_
22 
23 #include <new>
24 #include "OptionWidget.hpp"
25 #include "BWidgets/Label.hpp"
26 #include "DialRange.hpp"
27 
28 class OptionBanger : public OptionWidget
29 {
30 public:
OptionBanger()31 	OptionBanger () : OptionBanger (0.0, 0.0, 0.0, 0.0, "widget") {}
OptionBanger(const double x,const double y,const double width,const double height,const std::string & name)32 	OptionBanger (const double x, const double y, const double width, const double height, const std::string& name) :
33 		OptionWidget (x, y, width, height, name),
34 		gainLabel (0, 90, 80, 20, "ctlabel", BOOPS_LABEL_GAIN),
35 		firstLabel (80, 90, 80, 20, "ctlabel", BOOPS_LABEL_FIRST),
36 		lastLabel (160, 90, 80, 20, "ctlabel", BOOPS_LABEL_LAST),
37 		nukeLabel (240, 90, 80, 20, "ctlabel", BOOPS_LABEL_NUKE),
38 		speedLabel (320, 90, 80, 20, "ctlabel", BOOPS_LABEL_SPEED),
39 		spinLabel (400, 90, 80, 20, "ctlabel", BOOPS_LABEL_SPIN)
40 	{
41 		try
42 		{
43 			for (int i = 0; i < 5; ++i)
44 			{
45 				options[2 * i] = new DialRange (i * 80 + 10, 20, 60, 60, "pad0", 0.5, 0.0, 1.0, 0.0, BIDIRECTIONAL, "%1.2f");
46 				options[2 * i + 1] = new BWidgets::ValueWidget (0, 0, 0, 0, "widget", 0.0);
47 			}
48 			options[10] = new DialRange (410, 20, 60, 60, "pad0", 0.5, 0.0, 1.0, 0.0, BIDIRECTIONAL, "%1.2f", "", [] (double x) {return 2.0 * x - 1.0;}, [] (double x) {return 0.5 * (LIMIT (x, -1, 1) + 1.0);});
49 			options[11] = new BWidgets::ValueWidget (0, 0, 0, 0, "widget", 0.0);
50 		}
51 		catch (std::bad_alloc& ba) {throw ba;}
52 
53 		for (int i = 0; i < 12; i += 2)
54 		{
55 			options[i]->setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, valueChangedCallback);
56 			((DialRange*)options[i])->range.setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, rangeChangedCallback);
57 			options[i + 1]->setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, valueChangedCallback);
58 		}
59 
60 		add (gainLabel);
61 		add (firstLabel);
62 		add (lastLabel);
63 		add (nukeLabel);
64 		add (speedLabel);
65 		add (spinLabel);
66 		for (int i = 0; i < 12; ++i) add (*options[i]);
67 	}
68 
OptionBanger(const OptionBanger & that)69 	OptionBanger (const OptionBanger& that) :
70 		OptionWidget (that),
71 		gainLabel (that.gainLabel), firstLabel (that.firstLabel),
72 		lastLabel (that.lastLabel), nukeLabel (that.nukeLabel),
73 		speedLabel (that.speedLabel), spinLabel (that.spinLabel)
74 	{
75 		add (gainLabel);
76 		add (firstLabel);
77 		add (lastLabel);
78 		add (nukeLabel);
79 		add (speedLabel);
80 		add (spinLabel);
81 	}
82 
operator =(const OptionBanger & that)83 	OptionBanger& operator= (const OptionBanger& that)
84 	{
85 		release (&gainLabel);
86 		release (&firstLabel);
87 		release (&lastLabel);
88 		release (&nukeLabel);
89 		release (&speedLabel);
90 		release (&spinLabel);
91 		OptionWidget::operator= (that);
92 		gainLabel = that.gainLabel;
93 		firstLabel = that.firstLabel;
94 		lastLabel = that.lastLabel;
95 		nukeLabel = that.nukeLabel;
96 		speedLabel = that.speedLabel;
97 		spinLabel = that.spinLabel;
98 		add (gainLabel);
99 		add (firstLabel);
100 		add (lastLabel);
101 		add (nukeLabel);
102 		add (speedLabel);
103 		add (spinLabel);
104 
105 		return *this;
106 	}
107 
clone() const108 	virtual Widget* clone () const override {return new OptionBanger (*this);}
109 
applyTheme(BStyles::Theme & theme)110 	virtual void applyTheme (BStyles::Theme& theme) override {applyTheme (theme, name_);}
111 
applyTheme(BStyles::Theme & theme,const std::string & name)112 	virtual void applyTheme (BStyles::Theme& theme, const std::string& name) override
113 	{
114 		OptionWidget::applyTheme (theme, name);
115 		gainLabel.applyTheme (theme);
116 		firstLabel.applyTheme (theme);
117 		lastLabel.applyTheme (theme);
118 		nukeLabel.applyTheme (theme);
119 		speedLabel.applyTheme (theme);
120 		spinLabel.applyTheme (theme);
121 	}
122 
valueChangedCallback(BEvents::Event * event)123 	static void valueChangedCallback(BEvents::Event* event)
124 	{
125 		if (!event) return;
126 		BWidgets::Widget* widget = event->getWidget ();
127 		if (!widget) return;
128 		OptionWidget* p = (OptionWidget*) widget->getParent();
129 		if (!p) return;
130 		BOopsGUI* ui = (BOopsGUI*) widget->getMainWindow();
131 		if (!ui) return;
132 
133 		// options[i + 1] changed ? Send to range
134 		for (int i = 0; i < 12; i += 2)
135 		{
136 			if (widget == p->getWidget(i + 1))
137 			{
138 				((DialRange*)p->getWidget(i))->range.setValue (((BWidgets::ValueWidget*)widget)->getValue());
139 				break;
140 			}
141 		}
142 
143 		// Forward all changed options to ui
144 		ui->optionChangedCallback (event);
145 	}
146 
rangeChangedCallback(BEvents::Event * event)147 	static void rangeChangedCallback(BEvents::Event* event)
148 	{
149 		if (!event) return;
150 		BWidgets::Widget* widget = event->getWidget ();
151 		if (!widget) return;
152 		DialRange* p = (DialRange*) widget->getParent();
153 		if (!p) return;
154 		OptionWidget* pp = (OptionWidget*) p->getParent();
155 		if (!pp) return;
156 
157 		// Send changed range to options[i + 1]
158 		for (int i = 0; i < 12; i += 2)
159 		{
160 			if ((p == (DialRange*)pp->getWidget(i)) && (widget == (BWidgets::Widget*)&p->range))
161 			{
162 				p->update();
163 				((BWidgets::ValueWidget*)pp->getWidget(i + 1))->setValue (p->range.getValue ());
164 			}
165 		}
166 	}
167 
168 protected:
169 	BWidgets::Label gainLabel;
170 	BWidgets::Label firstLabel;
171 	BWidgets::Label lastLabel;
172 	BWidgets::Label nukeLabel;
173 	BWidgets::Label speedLabel;
174 	BWidgets::Label spinLabel;
175 };
176 
177 #endif /* OPTIONBANGER_HPP_ */
178