復習と理解度を深めるために、CascadePlugin全体のGUIを自作したいと思います。
類似した作業を何回もやってみることも大事だね~
前回までの検証で、JUCEのGUIの実装に関する整理と、一番原始的なGUIの追加方法の手順を整理できました。今回から、チュートリアルで作成したCascadePluginへGUIを実装していきたいと思います。
プログラミングも結構ボリュームがありますので、何回かに分けて進めていきたいと思います。今回はGUI作成のためのEditorクラスのヘッダに変更を行う部分を行います。
こんな人の役に立つかも
・JUCEフレームワークに入門したい人
・JUCEのGUIが作成したい人
・JUCEのCascadePluginチュートリアルをやっている人
ベースとするプロジェクト
以前の記事で作成したJUCEチュートリアルの「CascadePlugin」から作成していきました。今回実装するベースとなるCascadePluginは、以下のGitHubリポジトリにアップロード済みなので、もし実際に作成されるときは、お役に立てばと思います。
目標と手段の整理
プログラミングの方法として、最も原始的なGUIオブジェクトとパラメータ変数への紐づけ方法を利用してやっていきます。(AudioProcessorValueTreeStateを利用しません。また、GenericAudioProcessorEditorクラスを利用しません。)
今回必要となるComboboxクラスとToggleButtonクラスでのパラメータ変数への紐づけについては、以下の記事で検証しました。
Comboboxクラス
ToggleButtonクラス
コンボボックスとトグルボタンオブジェクトを利用して、今までGenericAudioProcessorEditorクラスで自動的に作成されていた部分を実装していきます。
パラメータ
必要となるコンボボックスは次の3つになります。
・processorSlot1~3の変数値を変化させるコンボボックス
必要となるチェックボックス(トグルボタン)は次の4つになります。
・入力音声ミュートのmuteInput変数をオンオフするトグルボタン
・各スロットのバイパスオンオフを制御するbypassSlot1~3変数を操作するトグルボタン
次のスクショはGenericAudioProcessorEditorクラスで自動的に作成したものですが、これと同じようなUI配置を行っていきます。
GUI側のプログラミング
今回はパラメータの導入部分の、リスナークラスの継承と、GUI変数の準備などを行います。これからGUIを作成するための準備という部分でしょうか。
「PluginEditor.h」へ次のようにプログラムを追記しました。
class CascadePluginAudioProcessorEditor : public juce::AudioProcessorEditor,
//[1]Listenerクラスの継承
private juce::ComboBox::Listener,//★[1]こちらがComboBox::Listenerクラスの継承
private juce::Button::Listener//★こちらがButton::Listenerクラスの継承です。
{
public:
//[2]リスナー関数のプロトタイプ宣言
void comboBoxChanged(juce::ComboBox* combo1) override;//★ComboBox::ListenerクラスのcomboBoxChanged関数をオーバーライドします。
void buttonClicked(juce::Button* mute) override;//★Button::ListenerクラスのbuttonClicked関数をオーバーライドします。
CascadePluginAudioProcessorEditor (CascadePluginAudioProcessor&);
~CascadePluginAudioProcessorEditor() override;
//==============================================================================
void paint (juce::Graphics&) override;
void resized() override;
private:
// This reference is provided as a quick way for your editor to
// access the processor object that created it.
CascadePluginAudioProcessor& audioProcessor;
//[3]GUIオブジェクトの定義
//★スロットを表現するコンボボックスオブジェクトを3つ定義します。
juce::ComboBox slot1;
juce::ComboBox slot2;
juce::ComboBox slot3;
//★入力音声のミュート、書くスロットのバイパスをオンオフするトグルボタンオブジェクトを計4個定義します。
juce::ToggleButton muteInputToggle;
juce::ToggleButton bypass1;
juce::ToggleButton bypass2;
juce::ToggleButton bypass3;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CascadePluginAudioProcessorEditor)
};
今回追加した部分は次の3点となります。
[1]Listenerクラスの継承
JUCEのGUIのクラスはリスナー関数という、値が変化したことを検知して実行される関数が実装されています。comboBoxクラスにはcomboBox::Listener、toggleButtonにはButton::Listenerというリスナー関数が定義されたクラスが存在します。
ここで注意点として、Buttonにはいろいろな種類があり、このButtonというクラスは「抽象クラス」で、Buttonを継承していろいろな種類のボタンクラスが作られています。今回利用するtoggleButtonは、もその一つで、Listenerを利用するときには、「Button::Listener」クラスのリスナー関数を利用することでtoggleButtonの変化を検出することができます。
Buttonクラスは理解するまで、少し戸惑いましたが、C++初めての方は「抽象クラス」が勉強できる良い題材になります。
実装例で使い方がわかるのは一番面白いよね~
[2]リスナー関数のプロトタイプ宣言
先ほど継承したListenerクラスのドキュメントを確認すると、メンバ関数としてついのようなものが確認できます。
・ComboBox::Listenerクラスには「comboBoxChanged」関数
・Button::Listenerクラスには「buttonClicked」関数
がリスナー関数として定義されていることがわかりました。(Button::Listenerクラスには、他にbuttonStateChangedという関数もありますが、ビルドの際に、buttonClicked関数がないとエラーになったので、buttonClicked関数を利用します。実質、クリックされたタイミングでボタンの状態を取得すればよいので、buttonClicked関数でよいのです。)
ということで、この[2]の部分で2つの関数をオーバーライドしています。
[3]GUIオブジェクトの定義
最後に、今回利用するGUIクラスを実際に格納する変数として、このようにprivateなメンバ変数として定義しています。必要なものは、コンボボックス3個、トグルボタン4個になります。