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 reloribute 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 loributed 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 OPTIONFILTER_HPP_
21 #define OPTIONFILTER_HPP_
22 
23 #include <new>
24 #include "OptionWidget.hpp"
25 #include "BWidgets/Label.hpp"
26 #include "DialRange.hpp"
27 
28 class OptionFilter : public OptionWidget
29 {
30 public:
OptionFilter()31 	OptionFilter () : OptionFilter (0.0, 0.0, 0.0, 0.0, "widget") {}
OptionFilter(const double x,const double y,const double width,const double height,const std::string & name)32 	OptionFilter (const double x, const double y, const double width, const double height, const std::string& name) :
33 		OptionWidget (x, y, width, height, name),
34 		loLabel (0, 90, 80, 20, "ctlabel", BOOPS_LABEL_HIGHPASS),
35 		hiLabel (90, 90, 60, 20, "ctlabel", BOOPS_LABEL_LOWPASS),
36 		ordLabel (170, 90, 60, 20, "ctlabel", BOOPS_LABEL_ROLL_OFF)
37 	{
38 		try
39 		{
40 			options[0] = new DialRange (10, 20, 60, 60, "pad0", 0.5, 0.0, 1.0, 0.0, BIDIRECTIONAL, "%1.0f", BOOPS_LABEL_HZ, [] (double x) {return 20.0 + 19980.0 * pow (x, 4.0);}, [] (double x) {return pow ((LIMIT (x, 20, 20000) - 20.0) / 19980.0, 0.25);});
41 			options[1] = new BWidgets::ValueWidget (0, 0, 0, 0, "widget", 0.0);
42 			options[2] = new DialRange (90, 20, 60, 60, "pad0", 0.5, 0.0, 1.0, 0.0, BIDIRECTIONAL, "%1.0f", BOOPS_LABEL_HZ, [] (double x) {return 20.0 + 19980.0 * pow (x, 4.0);}, [] (double x) {return pow ((LIMIT (x, 20, 20000) - 20.0) / 19980.0, 0.25);});
43 			options[3] = new BWidgets::ValueWidget (0, 0, 0, 0, "widget", 0.0);
44 			options[4] = new Dial (170, 20, 60, 60, "pad0", 0.5, 0.0, 1.0, 0.0, "%1.0f", BOOPS_LABEL_MINUS_DB_PER_OCTAVE, [] (double x) {return 12 * int (LIMIT (1.0 + 8.0 * x, 1, 8));}, [] (double x) {return (LIMIT (x, 12.0, 96.0) / 12.0 - 1.0) / 8.0;});
45 		}
46 		catch (std::bad_alloc& ba) {throw ba;}
47 
48 		options[0]->setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, valueChangedCallback);
49 		((DialRange*)options[0])->range.setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, rangeChangedCallback);
50 		options[1]->setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, valueChangedCallback);
51 		options[2]->setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, valueChangedCallback);
52 		((DialRange*)options[2])->range.setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, rangeChangedCallback);
53 		options[3]->setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, valueChangedCallback);
54 		options[4]->setCallbackFunction (BEvents::VALUE_CHANGED_EVENT, valueChangedCallback);
55 
56 		add (loLabel);
57 		add (hiLabel);
58 		add (ordLabel);
59 		for (int i = 0; i < 5; ++i) add (*options[i]);
60 	}
61 
OptionFilter(const OptionFilter & that)62 	OptionFilter (const OptionFilter& that) : OptionWidget (that), loLabel (that.loLabel), hiLabel (that.hiLabel), ordLabel (that.ordLabel)
63 	{
64 		add (loLabel);
65 		add (hiLabel);
66 		add (ordLabel);
67 	}
68 
operator =(const OptionFilter & that)69 	OptionFilter& operator= (const OptionFilter& that)
70 	{
71 		release (&loLabel);
72 		release (&hiLabel);
73 		release (&ordLabel);
74 		OptionWidget::operator= (that);
75 		loLabel = that.loLabel;
76 		hiLabel = that.hiLabel;
77 		ordLabel = that.ordLabel;
78 		add (loLabel);
79 		add (hiLabel);
80 		add (ordLabel);
81 
82 		return *this;
83 	}
84 
clone() const85 	virtual Widget* clone () const override {return new OptionFilter (*this);}
86 
applyTheme(BStyles::Theme & theme)87 	virtual void applyTheme (BStyles::Theme& theme) override {applyTheme (theme, name_);}
88 
applyTheme(BStyles::Theme & theme,const std::string & name)89 	virtual void applyTheme (BStyles::Theme& theme, const std::string& name) override
90 	{
91 		OptionWidget::applyTheme (theme, name);
92 		loLabel.applyTheme (theme);
93 		hiLabel.applyTheme (theme);
94 		ordLabel.applyTheme (theme);
95 	}
96 
valueChangedCallback(BEvents::Event * event)97 	static void valueChangedCallback(BEvents::Event* event)
98 	{
99 		if (!event) return;
100 		BWidgets::Widget* widget = event->getWidget ();
101 		if (!widget) return;
102 		OptionWidget* p = (OptionWidget*) widget->getParent();
103 		if (!p) return;
104 		BOopsGUI* ui = (BOopsGUI*) widget->getMainWindow();
105 		if (!ui) return;
106 
107 		// options[1 or 3] changed ? Send to range
108 		if (widget == p->getWidget(1)) ((DialRange*)p->getWidget(0))->range.setValue (((BWidgets::ValueWidget*)widget)->getValue());
109 		else if (widget == p->getWidget(3)) ((DialRange*)p->getWidget(2))->range.setValue (((BWidgets::ValueWidget*)widget)->getValue());
110 
111 		// Forward all changed options to ui
112 		ui->optionChangedCallback (event);
113 	}
114 
rangeChangedCallback(BEvents::Event * event)115 	static void rangeChangedCallback(BEvents::Event* event)
116 	{
117 		if (!event) return;
118 		BWidgets::Widget* widget = event->getWidget ();
119 		if (!widget) return;
120 		DialRange* p = (DialRange*) widget->getParent();
121 		if (!p) return;
122 		OptionWidget* pp = (OptionWidget*) p->getParent();
123 		if (!pp) return;
124 
125 		// Send changed range to options[1 or 3]
126 		if ((p == (DialRange*)pp->getWidget(0)) && (widget == (BWidgets::Widget*)&p->range))
127 		{
128 			p->update();
129 			((BWidgets::ValueWidget*)pp->getWidget(1))->setValue (p->range.getValue ());
130 		}
131 
132 		else if ((p == (DialRange*)pp->getWidget(2)) && (widget == (BWidgets::Widget*)&p->range))
133 		{
134 			p->update();
135 			((BWidgets::ValueWidget*)pp->getWidget(3))->setValue (p->range.getValue ());
136 		}
137 	}
138 
139 protected:
140 	BWidgets::Label loLabel;
141 	BWidgets::Label hiLabel;
142 	BWidgets::Label ordLabel;
143 
144 
145 };
146 
147 #endif /* OPTIONFILTER_HPP_ */
148