字幕列表 影片播放
Hey, what's up everybody?
大家好
I'd like to welcome you to another Audio Programmer tutorial.
歡迎您再次閱讀音頻程序員教程。
And in this tutorial, we're going to talk about the Juice Audio Processor Editor class.
在本教程中,我們將討論 Juice 音頻處理器編輯器類。
This is the base class that is used by Juice for any visual elements that you would like to use for your user interface.
這是 Juice 的基類,可用於用戶界面的任何可視化元素。
That is, what people see when they open up your plugin.
也就是說,人們在打開您的插件時會看到什麼。
The main objectives for this tutorial are to introduce you to the Audio Processor Editor class and the concept of components within Juice.
本教程的主要目的是向您介紹音頻處理器編輯器類和 Juice 中組件的概念。
To introduce you to the concept of parent and child components.
向您介紹父組件和子組件的概念。
I'll also show you how to create new source files within the CMake system to create child components.
我還將向你展示如何在 CMake 系統中創建新的源文件,以創建子組件。
And finally, we'll dig a little bit deeper into what happens when you load a plugin and how the editor is actually created in the plugin loading process.
最後,我們將深入探討加載插件時會發生什麼,以及在插件加載過程中如何創建編輯器。
As always, I'll also briefly discuss some of the core C++ concepts along the way for those who are just getting started.
與往常一樣,我還會簡要討論一些 C++ 的核心概念,供剛剛入門的讀者參考。
If you're ready to take that deeper dive into audio plugin development, I invite you to check out our books.
如果您準備深入學習音頻插件開發,我邀請您閱讀我們的書籍。
The Complete Beginner's Guide to Audio Plugin Development and Creating Synthesizer Plugins with C++ and Juice.
音頻插件開發完全入門指南》和《使用 C++ 和 Juice 創建合成器插件》。
These are great resources to get started.
這些都是很好的入門資源。
All in all, there's about 900 pages on how to start creating your own plugins.
關於如何開始創建自己的插件,總共有大約 900 頁。
I invite you to check them out on theaudioprogrammer.com forward slash books.
我邀請你到 theaudioprogrammer.com forward slash books 上查看它們。
Link is in the description below.
鏈接在下面的說明中。
This video is also brought to you in part by our sponsor JetBrains.
本視頻的部分內容也是由我們的贊助商 JetBrains 提供的。
If you're looking for ways to streamline your development process, I invite you to check out their amazing C-Line IDE.
如果您正在尋找簡化開發流程的方法,我邀請您去看看他們令人驚歎的 C-Line 集成開發環境。
Their tools have helped me to exponentially speed up my workflow and I'm proud to be a supporter.
他們的工具幫助我成倍地加快了工作流程,作為他們的支持者,我深感自豪。
Be sure to check out more on the link in the description below.
請務必通過下面的鏈接查看更多資訊。
And with that being said, let's get started.
說了這麼多,讓我們開始吧。
OK, so right now we're in a blank Juice plugin template project.
好了,現在我們在一個空白的 Juice 插件模板項目中。
If you're not sure how to get to this point, be sure to check out our tutorial called CMake vs.
如果您不確定如何達到這一點,請務必查看我們的教程《CMake vs. CMake》。
ProJuice or FaceOff, which shows you how to start creating a project that will help you get up and running.
ProJuice 或 FaceOff,告訴你如何開始創建一個項目,幫助你啟動和運行。
And as I was saying before, we're going to use CMake for tutorials from here on out.
正如我之前所說,從現在開始,我們將使用 CMake 製作教程。
It's the industry standard.
這是行業標準。
And I think that even though it's more difficult to get started, it will definitely help you in the long run.
我認為,儘管起步比較困難,但從長遠來看,這肯定會對你有所幫助。
So where we are now is in the Audio Plugin Audio Processor Editor class.
是以,我們現在所處的位置是音頻插件音頻處理器編輯器類。
So as we can see, we have four files that are over here on the left hand side.
我們可以看到,左手邊有四個文件。
Plugin Editor.cppnh and Plugin Processor.cppnh.
Plugin Editor.cppnh 和 Plugin Processor.cppnh。
Plugin Processor is what we went through last tutorial where we talked about the Audio Processor class.
Plugin Processor(插件處理器)是我們在上一教程中討論過的音頻處理器類。
And that is where the actual audio processing happens for your plugins.
這也是對插件進行實際音頻處理的地方。
So not the part that you see, but the actual audio processing.
所以,不是你看到的那部分,而是實際的音頻處理。
The Audio Processor Editor class is what you actually see when you load your plugin.
音頻處理器編輯器類是您在加載插件時實際看到的內容。
So if I just go ahead and I compile this here, we can see that this plugin is loaded.
是以,如果我繼續編譯這個插件,就能看到插件已加載。
We're in standalone mode right now.
我們現在處於獨立模式。
And that what we actually see, this is the Audio Processor Editor.
這就是我們實際看到的音頻處理器編輯器。
Now, if we dive a little bit deeper into this class, we can see that it inherits from this class called the Audio Processor Editor class.
現在,如果我們深入研究一下這個類,就會發現它繼承自這個名為音頻處理器編輯器類的類。
So what I'm going to do is I'm going to jump into this class now.
所以,我現在要做的就是跳進這個班級。
And what we'll see is that the Audio Processor Editor class is a juice class.
我們將看到,音頻處理器編輯器類是一個果汁類。
And this in turn inherits from the component class.
而這又繼承自組件類。
So the component class is essentially any visual element that you have within juice.
是以,組件類基本上就是果汁中的任何可視化元素。
So when you load up some type of visual class in juice or you're creating some type of visual element, it will inherit from this component class.
是以,當你在 juice 中加載某種類型的可視化類或創建某種類型的可視化元素時,它將從這個組件類繼承。
And what I'll do here is I'll actually show you the juice documentation because sometimes it's nice to see it this way as well, which is that we have this Audio Processor Editor class.
在這裡,我會向你展示果汁文檔,因為有時這樣看也不錯,我們有這個音頻處理器編輯器類。
And then this is what's called an inheritance diagram, which shows you where in the hierarchy these classes inherit from.
這就是所謂的繼承圖,它顯示了這些類在層次結構中的繼承位置。
So it says here that the juice Audio Processor Editor class inherits from the juice component class.
是以,這裡說 juice 音頻處理器編輯器類繼承自 juice 組件類。
So anything that you can do with a component class, you can do with an Audio Processor Editor class because Audio Processor Editor inherits from component.
是以,只要是組件類能做到的,音頻處理器編輯器類也能做到,因為音頻處理器編輯器繼承自組件。
OK, so now let's just jump back into the source code here.
好了,現在讓我們回到源代碼中。
Here we have four functions that are in this class.
在這裡,我們有四個屬於這一類的函數。
And this is pretty typical for what you would see within any type of component or visual element class.
這對於任何類型的組件或可視化元素類來說都是非常典型的。
You would have a constructor and a destructor that are called when the window is created or destroyed.
窗口創建或銷燬時會調用一個構造函數和一個析構函數。
And you have this paint function, which is more for things that you would do within that component itself.
此外,你還可以使用 "繪製 "功能,它更多地用於在組件本身中進行操作。
So if you wanted to write some text, for example, we have the window currently saying hello world.
是以,如果你想寫一些文字,例如,我們的窗口目前正在寫 "hello world"。
If we wanted to change the color of the background, if we wanted to change the size of the text, we would do that within paint.
如果我們想改變背景的顏色,如果我們想改變文字的大小,我們都可以在油漆中完成。
And then we have this resized function, which is where we would actually lay out any type of other components that we want to sit inside of this Audio Processor Editor.
然後,我們有一個調整大小的功能,在這裡,我們可以實際佈局我們想要放在音頻處理器編輯器中的任何其他組件。
So I'm going to describe that in a little bit more detail here by going to the CPP file, which is the actual implementation of these function calls.
是以,我將通過 CPP 文件對其進行更詳細的描述,CPP 文件是這些函數調用的實際實現。
So as I said before, first thing that we have is the constructor.
是以,正如我之前所說,我們的第一件事就是構造函數。
And I won't go really into what these are because I don't think that they're relevant so much for getting started.
至於這些是什麼,我就不多說了,因為我覺得它們與入門沒有太大關係。
But what we see down here is we have this set size, which at the moment is 400 by 300 pixels.
但我們在這裡看到的是我們設定的尺寸,目前是 400 x 300 像素。
Right.
對
So if we just go ahead and build that now, we see that this is 400 by 300 pixels.
是以,如果我們現在繼續創建,我們會看到這是 400 x 300 像素。
And if I wanted to change this, let's say I wanted to change it to a 600 pixel height and then we just rebuild this here, then we will see that now the plugin has got taller.
如果我想改變這個,比方說我想把它改成 600 像素的高度,然後我們在這裡重建這個,那麼我們就會看到現在插件變高了。
Right.
對
So as I was saying before, for people who are just getting started, the constructor is what's being called when the window is first created.
是以,正如我之前所說,對於剛剛入門的人來說,構造函數就是窗口首次創建時調用的函數。
And then the destructor is what happens when the when the window is destroyed.
然後,當窗口被銷燬時,析構函數就會發生作用。
Now, one thing that I will say that was a common mistake that I used to think about when I was first getting started and one that I see very often for other people who are getting started is that when when we're in a DAW, let's say we're in Ableton Live or in Reaper, that it's very easy to think that if we close out the plugin, that the plugin window is actually being minimized.
現在,我要說的是,我在剛開始使用插件時經常會犯的一個錯誤,我也經常看到其他剛開始使用插件的人犯這個錯誤,那就是當我們在 DAW 中,比如說在 Ableton Live 或 Reaper 中,很容易認為如果我們關閉插件,插件窗口就會被最小化。
That's how I used to think of it in my mind, because when you pull up the window again, all of the parameters and dials and sliders are all in the same place where you left them.
我以前就是這麼想的,因為當你再次打開窗口時,所有的參數、刻度盤和滑塊都在你離開的地方。
Or at least they're supposed to be if the person made the plugin properly.
或者說,如果製作者正確地製作了插件,至少應該是這樣的。
So because of that, I used to think that this window was actually being minimized.
是以,我一直以為這個窗口實際上被最小化了。
But one thing one key thing to think about is that the window is actually being destroyed.
但是,有一件事是必須考慮的,那就是窗戶實際上正在被破壞。
So it actually does not exist anymore.
是以,它實際上已經不存在了。
You'll learn a little bit more about this as we get a little bit further in the plugin development.
隨著插件開發的深入,您會了解到更多這方面的資訊。
But one great example of where this mistake is made is when it comes to sliders that are holding some type of value.
但有一個很好的例子可以說明這種錯誤,那就是當涉及到具有某種價值的滑塊時。
So when it's holding that value, it's very important that the value of the slider that is sitting within this plugin window is able to relay what the value of the slider is over to the plugin processor.
是以,當它保持該值時,插件窗口中的滑塊值必須能夠將滑塊的值傳遞給插件處理器,這一點非常重要。
Because if it doesn't, and you're relying on that value to be there, and the plugin window is destroyed, then it doesn't exist anymore.
因為如果它不存在,而你又依賴於該值的存在,那麼插件窗口被破壞後,它就不存在了。
And you're going to be trying to look for a value that does not exist.
你將試圖尋找一個不存在的值。
So once again, that gets a little bit, that's jumping ahead a little bit.
所以,這又有點,有點跳躍了。
But it's just something to keep in mind that as you're going through this journey, that when you're creating this window, that when you close it out, it's not minimized.
但需要注意的是,在你經歷這段旅程時,當你創建這個窗口時,當你關閉它時,它不會被最小化。
It actually does not exist anymore.
實際上,它已經不存在了。
Okay.
好的
So jumping down a little bit further, we have this function that's called paint.
再往下跳一點,我們有一個名為 "塗抹 "的函數。
So paint, I would think of as what you actually want to happen within this visual component itself.
是以,我認為繪畫就是你希望在這個視覺組件中發生的事情。
So as we can see, we have this g.fillall, which is filling the background of the component with this green color.
是以,正如我們所看到的,我們使用 g.fillall,將組件的背景填充為綠色。
Now, what I could do is I could actually change this color.
現在,我可以做的就是改變這種顏色。
Let's just go ahead and change it to black.
我們還是把它改成黑色吧。
And what I can do is, oh, I need to get rid of this bracket.
我能做的就是,哦,我得把這個支架去掉。
And what I could do is I could recompile this.
我可以做的就是重新編譯。
And then what we should see is now the plugin window is black, right?
然後我們應該看到插件窗口是黑色的,對嗎?
And if I wanted to change this text to red, and I wanted to make it a little bit bigger, I would just do that here.
如果我想把文字改成紅色,並把它放大一點,就可以在這裡完成。
So the size of this text is being set by this g.setfont.
是以,文字的大小是由 g.setfont 設置的。
So if I wanted to change this from 15 to 30, and then if I wanted to change the color from white to red, this is where all of that would happen.
是以,如果我想把這個數字從 15 改為 30,然後把顏色從白色改為紅色,所有這些都會在這裡實現。
So paint, once again, is the place where the things that are actually happening within this component itself are being changed.
是以,油漆又一次成為了這一部件內部實際發生變化的地方。
Now coming down to the resize function, we see that there's nothing that's happening inside of this at the moment.
現在來看看調整大小功能,我們可以看到,目前這個功能內部什麼也沒發生。
And this brings us to another principle of these component classes, which is that components can hold other components.
這就引出了這些組件類的另一個原則,即組件可以容納其他組件。
So when I say component, think a window, like a visual window.
所以,當我說 "組件 "時,你要想到一個窗口,就像一個可視窗口。
And these components can have other components inside of them.
這些組件內部還可以有其他組件。
And the way that you would lay those out is typically in this resized function.
通常情況下,你可以通過這個調整大小的功能來佈局這些內容。
Okay, so what we're going to do now is we're going to create our own component class.
好了,現在我們要做的就是創建自己的組件類。
And we're going to include it as a child within this plugin editor class that we have here.
我們將把它作為一個子類包含在這個插件編輯器類中。
Okay, so if that sounds like a daunting task, don't worry, I'm going to take you step by step.
好吧,如果這聽起來像是一項艱鉅的任務,別擔心,我會一步一步地教你。
And I feel confident that if you follow along, that you're going to come out successfully on the other side.
我相信,只要你跟著我走,就一定能成功到達彼岸。
So let's go ahead and get started.
那麼,讓我們開始吧。
First thing that we're going to need to do if we want to create a component class is we're going to need to create some source files.
要創建一個組件類,我們首先需要創建一些源文件。
So the way that we're going to do that is we're going to go over here to our source folder over here in our Explorer.
是以,我們要做的就是在資源管理器中進入源文件夾。
We're going to right click and create a new C++ class.
我們點擊右鍵,創建一個新的 C++ 類。
So this is how you would do it in SceneLion.
是以,您可以在 SceneLion 中這樣做。
If you were working in Xcode or Visual Studio, it essentially be a similar type of command.
如果您在 Xcode 或 Visual Studio 中工作,基本上也是類似的命令類型。
So now I'm going to go ahead and create this.
現在我要繼續創建這個。
And I will just call this, let's just call it square.
我把它叫做 "正方形"。
And I will create a .cpp and .header file for this new class that we're calling square.
我將為這個我們稱之為 square 的新類創建 .cpp 和 .header 文件。
And I'm going to hit OK.
然後我就按 "確定 "鍵。
And now we've created those new source files.
現在我們已經創建了這些新的源文件。
I'm just going to hit add.
我就點擊添加。
And now we have some new source files.
現在我們有了一些新的源文件。
And what I'm going to do is I'm just going to get rid of everything just so it's blank.
而我要做的,就是把所有東西都去掉,讓它一片空白。
And we'll start from complete scratch.
我們將從頭開始。
The next thing that we need to do is we need to now include this within our CMake file.
接下來我們要做的就是在 CMake 文件中加入這個文件。
So the reason that we need to do this is if we look at our current CMake file, we can see here that the source files that we've included so far are plug-in editor.cppnh and plug-in processor.cppnh.
是以,我們需要這樣做的原因是,如果我們查看一下當前的 CMake 文件,就會發現到目前為止我們包含的源文件是 plug-in editor.cppnh 和 plug-in processor.cppnh。
And so it doesn't know at the moment that square.cppnh are supposed to be part of our build system, part of the files that we want to use and include in our project.
是以,它目前還不知道 square.cppnh 應該是我們構建系統的一部分,是我們想要使用幷包含在項目中的文件的一部分。
So just to show you here, if I go into the source folder and just open it up in the finder, here we are in our project.
如果我進入源代碼文件夾並在查找器中打開它,就會看到我們的項目。
You see cmakelist.txt here.
請參見 cmakelist.txt。
And there's the source folder.
這就是源文件夾。
I'm just going to double-click in there.
我只需在這裡點擊兩下。
And there we see our class, all of our source files, in fact, square.cppnh and all of our other ones.
在這裡,我們可以看到我們的類和所有源文件,事實上,還有 square.cppnh 和其他所有文件。
Now, what we need to do is we need to include this in our CMake file.
現在,我們需要做的是將其包含在 CMake 文件中。
Now, the reason that you need to say source slash dot plug-in editor and slash square dot h and cpp is because the declaration that you're making inside the CMake file needs to be relative to where the cmakelist.txt resides.
現在,之所以需要用斜線點插件編輯器源代碼和斜線方形點 h 和 cpp,是因為在 CMake 文件中進行的聲明需要相對於 cmakelist.txt 所在的位置。
So here we are in our project.
我們的項目就這樣開始了。
We see that we have this cmakelist.txt, and then we have this source folder.
我們可以看到 cmakelist.txt,然後是源文件夾。
So we need to say relative to the cmakelist.txt file, we're going into source and into these files.
是以,我們需要說,相對於 cmakelist.txt 文件,我們要進入源代碼,進入這些文件。
If we had another folder that we just, let's say we called it code, for instance, and we put these files in here, then in our cmakelist.txt, it would need to say source slash code slash whatever your source file is.
如果我們有另一個文件夾,比方說,我們把它叫做代碼,並把這些文件放在這裡,那麼在 cmakelist.txt 中,就需要寫上 source slash code slash(源文件斜線代碼斜線),不管你的源文件是什麼。
So that's the reason why the convention is being named this way.
所以,這就是為什麼大會要這樣命名的原因。
Okay, so now we're going to put our square class files in here.
好了,現在我們要把方形類文件放在這裡。
So we've got square.cpp, source, square.h.
所以我們有 square.cpp、source、square.h。
And now those are included.
現在這些都包括在內了。
Now, if you're in Visual Studio or in Xcode, what you're going to need to do to update your CMake build is you're going to need to invoke CMake, which is that normal command that you normally do, which is cmake-bbuilds-gxcode or whatever your command is, right?
現在,如果您在 Visual Studio 或 Xcode 中,要更新 CMake 編譯,您需要調用 CMake,也就是您通常使用的 cmake-bbuilds-gxcode 或其他命令,對嗎?
If you're here in SceneLine, it actually has CMake integrated into the IDE, and I can just hit this little reload CMake project, and it'll actually run CMake here inside the IDE.
如果你在 SceneLine 中,它實際上已將 CMake 集成到集成開發環境中,我只需點擊這個重新加載 CMake 項目的小按鈕,它就會在集成開發環境中運行 CMake。
So that's one of the things I really love about CMake here in SceneLine.
這也是我非常喜歡 SceneLine 中 CMake 的一點。
So there we go.
就這樣吧。
So that's run, and now we're all good to go.
就這樣,現在我們都可以走了。
So now we have this square.h source file, and we're going to build this from scratch.
現在我們有了這個 square.h 源文件,我們將從頭開始構建它。
So the first thing that we're going to do is we're going to declare pragma once.
是以,我們要做的第一件事就是聲明一次 pragma。
The reason that we do this is because what we need to do is we're going to need to include some other source files to be able to give this class that we're creating some functionality.
這樣做的原因是,我們需要包含一些其他源文件,以便為我們創建的這個類提供一些功能。
So right now this source file knows nothing about Guice.
是以,現在這份源文件對吉斯一無所知。
It knows nothing about anything except for basic C++, and what we're going to need to do is include a graphics library from Guice in order to be able to inherit the component class, which allows us to create the window, okay?
除了基本的 C++ 之外,它對其他任何東西都一無所知。我們需要做的是加入 Guice 的圖形庫,以便能夠繼承組件類,從而創建窗口,明白嗎?
If we had another class that was using another include that was using the graphics library, and we included it, what pragma once does is it creates us from having name collisions where you're including source files more than one time.
如果我們有另一個使用圖形庫的包含類,並且我們包含了它,那麼 pragma once 的作用就是讓我們避免在包含源文件時出現名稱衝突。
So it says, okay, he's already included the Guice graphics library, so we don't need to include that again.
所以它說,好吧,他已經包含了 Guice 圖形庫,所以我們不需要再包含了。
So that's what pragma once is for.
這就是 pragma once 的作用。
So the first thing that we'll do is we'll just create this basic class.
是以,我們要做的第一件事就是創建這個基本類。
The way we do this is called class.
我們這樣做的方式叫做 "上課"。
I'm just going to call this square, and now I've created my class, okay?
我把它叫做 "正方形",現在我創建了我的類,好嗎?
Now square does not have any functionality right now, so it doesn't know anything about being a Guice component, doesn't know anything about Guice, doesn't know anything about anything except for basic C++.
現在,square 沒有任何功能,所以它不知道如何成為一個 Guice 組件,不知道任何關於 Guice 的事情,除了基本的 C++ 之外,它什麼都不知道。
In order for us to be able to give square the functionality that it needs, we need to be able to inherit from the Guice component class, okay?
為了給 square 提供所需的功能,我們需要繼承 Guice 組件類,好嗎?
So the way that we do that is that if we look to our Guice documentation, you'll see that we want to inherit this component class to give it the functionality where it can draw a window within our project.
是以,如果我們查看 Guice 文檔,就會發現我們希望繼承這個組件類,使其具備在項目中繪製窗口的功能。
Now, Guice is a collection of libraries.
現在,Guice 是一個圖書館集合。
So you have DSP libraries, you have graphics libraries, you have all of these different libraries that you can use.
是以,你可以使用 DSP 庫、圖形庫以及所有這些不同的庫。
The way that you can find out what library that you need to include is here in the Guice documentation.
您可以在 Guice 文檔中找到需要包含哪些庫。
If you look below this Guice component class reference, it'll normally have the name of the library that you need to include right here, which in this case is Guice underscore GUI underscore basics.
如果你查看這個 Guice 組件類引用的下方,通常會有你需要包含的庫的名稱,在本例中就是 Guice 下劃線 GUI 下劃線基礎知識。
So the way that you would do this is here we go below the pragma once.
是以,我們要做的就是在 pragma 下面輸入一次。
And what I will do is I'll do a hashtag include.
我會做的是加入一個標籤。
And I'm actually going to get rid of the quotes because one thing that I learned is that for library includes, you actually use angle brackets rather than quotes for those.
實際上,我打算去掉引號,因為我學到的一件事是,對於庫包含的內容,實際上應該使用角括弧,而不是引號。
So now what I can do is I can use Guice GUI basics.
是以,現在我可以使用 Guice 圖形用戶界面基礎知識。
And so that leads us to the folder that it's in.
這就引出了它所在的文件夾。
And then Guice GUI basics dot H.
然後是 Guice GUI 基礎點 H。
OK, so now what we can do is we can we can now invoke anything that's within this Guice GUI basics library.
好了,現在我們可以做的就是調用 Guice GUI 基礎庫中的任何內容。
OK, there's another way that you can that you can do this.
好吧,還有一種方法可以做到這一點。
That's where you can say include Guice header dot H and that will give you access to all of the Guice library code.
在這裡,你可以說 include Guice header dot H,這樣就可以訪問所有 Guice 庫代碼。
But I would say that this is the more correct and more optimized way to do this.
但我想說,這是更正確、更優化的方法。
OK, so now what we can do is we can inherit Guice component.
好了,現在我們可以繼承 Guice 組件了。
So the way that we do this is we just put a little colon here and we need to declare it as public or private first.
是以,我們要做的就是在這裡加上一個小冒號,然後首先聲明它是公共的還是私有的。
So we want this to be a public class.
是以,我們希望這是一個公共類。
And then we got Guice colon colon component.
然後我們得到了吉斯結腸的結腸成分。
OK, so now we've inherited the Guice component class.
好了,現在我們已經繼承了 Guice 組件類。
So now what we can do is we can call upon in this class anything that that a Guice component is able to do.
現在,我們可以在這個類中調用 Guice 組件能做的任何事情。
OK, so a lot of the next functionality that we're going to need is going to be very similar to what we've done with the plugin editor.
好了,接下來我們需要的很多功能都將與插件編輯器非常相似。
OK, so here in the plugin editor we have four functions which are the constructor, the destructor, paint and resized.
好了,在插件編輯器中,我們有四個函數,分別是構造函數、析構函數、繪製函數和調整大小函數。
To keep things super simple, I'm going to just do paint and resize.
為了讓事情變得超級簡單,我將只進行繪製和調整大小。
And what I'll do is I'll just literally copy here from this audio processor editor.
我要做的就是從音頻處理器編輯器中複製這裡的內容。
And I'm just going to paste it in square.h.
我將把它粘貼到 square.h 中。
The reason that I'm not worrying about including the constructor or the destructor is because we don't need to do anything with that in this tutorial.
我之所以不擔心包含構造函數或析構函數,是因為在本教程中我們不需要做任何事情。
So I'm not going to complicate it for you.
所以,我不想把問題複雜化。
So now what I'm going to do is I'm going to go here into this class square.
現在我要做的,就是進入這個類方格。
And these need to be public functions that we can publicly access.
這些功能必須是我們可以公開訪問的公共功能。
And I'm just going to go ahead and paste those in like so.
我就這樣把它們粘貼進去。
OK, because we want very similar functionality to what we have with our with our plugin editor class, which is also a Guice component.
好的,因為我們需要的功能與插件編輯器類的功能非常相似,而插件編輯器類也是一個 Guice 組件。
So we're going to want to just to review going back to plugineditor.cpp.
是以,我們需要回顧一下 plugineditor.cpp。
In this in this situation, we're going to want to just give our component some color.
在這種情況下,我們只想給我們的組件添加一些顏色。
So fill the the rectangle with a color and maybe do some writing.
是以,在矩形中填入一種顏色,或許還可以寫上一些文字。
And that's it.
就是這樣。
In fact, we probably don't need resized for to put in this square class, but I'll just do it just for just just to show you how to do it.
事實上,我們可能不需要調整這個方形類的大小,但我還是要做一下,只是為了給大家演示一下。
So the next thing that we need to do is we need.
是以,接下來我們需要做的是
So now we've declared these functions.
現在我們已經聲明瞭這些函數。
What we need to do is we need to provide implementations for these functions.
我們需要做的是為這些功能提供實現方法。
So the way that we do this is go over to square.cpp.
是以,我們要做的就是轉到 square.cpp。
Make sure that you have hashtag include square.h there or else it won't know what you're talking about.
確保你的標籤包含 square.h,否則它就不知道你在說什麼。
And what I'm going to do is I'm just going to paste.
我要做的就是粘貼。
I'm just going to paste these in there.
我就把這些粘貼在這裡。
And just to go back to square.h for for a second, just to reiterate, we are doing the override keyword for for paint and for resize because those are functions that are created from Guice component.
再回過頭來看一下 square.h,重申一下,我們之所以使用覆蓋關鍵字來覆蓋繪製和調整大小,是因為這些函數是由 Guice 組件創建的。
So we have if we look at paint.
所以,如果我們看一下油漆,就會發現。
We can see that that's a virtual function.
我們可以看到,這是一個虛擬函數。
So the reason that we wanted that we want to include this is because we want to be able to to paint our component a certain color.
所以,我們之所以要加入這個功能,是因為我們希望能把組件塗成某種顏色。
And in order to do that, we need to include the paint functionality, which is happening through this function.
要做到這一點,我們需要包含繪製功能,而這正是通過這個函數實現的。
So that's the reason why this is happening.
所以,這就是發生這種情況的原因。
So now to implement these functions, I'm going to just put some angle brackets here.
現在,為了實現這些功能,我只需在這裡加上一些角括號。
Curly brackets, as they call them.
他們稱之為 "捲曲括號"。
Now, there's one more thing that we need to do, and this is just something I'm once again reiterating for people who are just getting started, which is that.
現在,我們還需要做一件事,這是我再次向剛剛開始工作的人重申的,那就是。
If you have a lot of paint functions, if you have a lot of components, then then when your code is compiling, it doesn't know which paint you're referring to when when you're trying to call this particular paint.
如果你有很多油漆函數,如果你有很多組件,那麼當你的代碼在編譯時,當你試圖調用這個特定的油漆時,它就不知道你指的是哪個油漆。
OK, because we don't have what's called a qualified class name in front of it.
好吧,因為我們前面沒有所謂的限定類名。
So because we want to call the paint function that's specific to square, what we want to do is we want to do this.
是以,由於我們要調用專門針對正方形的繪製函數,我們要做的就是這樣做。
Which is we're saying that we want to call these the paint function, but the paint function that is specific to the class square.
也就是說,我們要調用這些繪製函數,但繪製函數是方形類特有的。
OK, so that's once again, just kind of basics of C++, but but stuff that stuff that is essential to know.
好了,以上又是 C++ 的基礎知識,但這些都是必須知道的。
And so I did that for resized as well.
是以,我也調整了尺寸。
Now from here, now we have a component class.
現在,我們有了一個組件類。
OK, now we just need to give it a little bit of functionality.
好了,現在我們只需要賦予它一點功能。
And the way that we'll do this, once again, I'll just go over here to the plugin editor that CPP.
我們這樣做的方法是,我再一次進入 CPP 的插件編輯器。
And, you know, if you don't if you don't have these these calls memorized, you know, all you need to do is just copy it from something that works and just pop it in there and change a few things.
而且,你知道,如果你沒有記住這些電話,你需要做的就是從有效的地方複製過來,然後把它放進去,再改動幾處就可以了。
OK, so that's a great way to get started.
好了,這就是開始的好方法。
So first thing that we see is that we are getting an error here on this G.
是以,我們看到的第一件事就是 G 出現了錯誤。
It doesn't know what G is, and that's because it just says juice graphics ampersand and it doesn't have a doesn't have a variable name there.
它不知道 "G "是什麼,因為它只寫了果汁圖形符號,沒有變量名。
So I just need to pop that G in there for it to know what what the graphics object is or just to be able to refer to that.
是以,我只需將 G 放進去,它就能知道圖形對象是什麼,或者只是能夠引用它。
Now, what I'm going to do is I can just change a few things around.
現在,我要做的就是改變一些東西。
OK, so if I'm going to change the background color, I can change it here.
好了,如果要更改背景顏色,我可以在這裡更改。
Let's just change it to orange.
還是換成橙色吧。
And then we'll set the color of the of the font to white.
然後將字體顏色設置為白色。
I'm just going to make it a little bit smaller.
我只是想把它變小一點。
And then.
然後
I will just.
我就
Say here the audio programmer.
這裡說的是音頻程序員。
So there we go.
就這樣吧。
So I've just changed a couple of things around, repurpose some code that I found in a component class that already works.
是以,我只是改動了一些地方,重新使用了我在一個組件類中發現的一些代碼,這些代碼已經可以正常工作了。
And so now we have a component class that we've just created.
現在,我們有了一個剛剛創建的組件類。
So congratulations, you have your very first component class.
恭喜你,你有了自己的第一個組件類。
So now if we build, we just want to make sure that this code is working OK so far.
是以,現在如果我們構建,我們只想確保這段代碼目前運行正常。
And we can see that we don't see anything else.
我們可以看到,我們看不到其他任何東西。
We don't see this window that we've just created.
我們看不到剛剛創建的窗口。
The reason that we don't see it is because we haven't actually included it as a child to this to to our main window.
我們看不到它的原因是,我們實際上並沒有將它作為主窗口的子窗口。
So the way that we need to do this is we need to go back and we need to go into our plug in our plug in editor class.
是以,我們需要做的就是返回到我們的插件中,進入我們的插件編輯器類。
And now what we need to do is we need to include square dot H.
現在我們需要做的是加入方形圓點 H。
OK, because that's that's the component that we've just created.
好的,因為這就是我們剛剛創建的組件。
So here I'm going to do a include.
是以,我要在這裡做一個包括。
Square dot H.
方形圓點 H。
So now I have said that I want to bring in this code from square H and be able to do something with it.
所以,現在我說,我想從 H 方引入這些代碼,並能用它們做一些事情。
And now what I want to do.
現在我要做的是
Is I want to create a square object.
我想創建一個正方形對象。
I want to create a square component.
我想創建一個正方形組件。
I'm just going to call this square.
我就把它叫做 "正方形"。
And now I've created an object within our editor.
現在,我在編輯器中創建了一個對象。
And now what I'm going to do is go to the CPP file.
現在我要做的是打開 CPP 文件。
I'm going to go up here to the constructor and they have this special function that is specific to the component class called add and make visible.
我將進入構造函數,它有一個專門針對組件類的特殊函數,叫做添加並使其可見。
Now what this does, if we go back to our documentation.
現在,如果我們回過頭來看我們的文檔,就會發現它的作用。
And if I can get to it quickly.
而且如果我能儘快趕到的話。
So it says adds a child component to this one and makes the child visible if it isn't already.
是以,它說的是在這個組件上添加一個子組件,並使尚未可見的子組件可見。
OK, so so that's what that's doing.
好吧,原來如此。
So remember that concept earlier that I was explaining about parent and child components.
還記得我之前解釋的父組件和子組件的概念嗎?
What we're doing is we're making square a child component of audio plug in audio processor editor.
我們要做的是,讓 square 成為音頻插件中音頻處理器編輯器的子組件。
So we're saying we want we want square to be a window that's inside this other window that we've that was already created for us.
所以我們說,我們希望正方形是一個窗口,位於我們已經創建的另一個窗口內。
Our main plug in window.
我們的主要插件窗口。
The last thing that we need to do is we need to actually put it on the screen and say where we want it to be on the screen.
最後,我們需要把它放到螢幕上,並說明我們希望它出現在螢幕的哪個位置。
And we do that in this resized function.
我們在這個調整大小的函數中實現了這一點。
And the way that we do that is we would say square.
我們的做法是,我們會說正方形。
And then there are many different ways to do this.
這樣做的方法有很多種。
Many, many different ways to do this.
有很多很多不同的方法可以做到這一點。
The easiest is using this set bounds function here.
最簡單的方法就是使用這裡的設置邊界功能。
And so if we go back to the documentation again.
是以,如果我們再次回到文件中。
If we go to set bounds.
如果我們去設定邊界。
We'll see we'll see that there are a lot of different ways that you can that you can actually set bounds.
我們會發現,有很多不同的方法可以設置界限。
The way that we're going to use in this instance is just using an X a Y giving it a width and giving it a height in pixels.
在本例中,我們要使用的方法是使用一個 X 和一個 Y,以像素為組織、部門給出寬度和高度。
So we're just saying where we where we want to set it on the X axis.
所以,我們只是說我們想把它設置在 X 軸的哪個位置。
Set it where we want to set it on the Y axis and how wide and how tall we want it to be.
在 Y 軸上設置我們想要的位置,以及我們想要的寬度和高度。
Just a note that component classes are rectangles and that the X and Y position will be relative to the top left of the rectangle.
請注意,組件類是矩形,X 和 Y 位置將相對於矩形的左上角。
OK.
好的。
So not to the center but to the top left.
所以不是向中間,而是向左上方。
So just a little thing to keep in mind there.
所以,有一點要記住。
So we're going to give it an X position.
所以我們要給它一個 X 位置。
Just make it 100. 100.
只要100。100.
And then I'll give it a width.
然後我再給它加寬。
Let's say that it's 200 by 200.
假設是 200 乘 200。
And now we're going to go ahead and build it.
現在,我們將繼續建造它。
And if everything works properly we should see a square within another square.
如果一切正常,我們就會看到一個正方形中又有一個正方形。
There we go.
好了
So now we have created a child component that's within this larger component here.
現在,我們在這個大組件中創建了一個子組件。
And as you can see it says the audio programmer inside of it.
正如你所看到的,裡面寫著音頻編程器。
The background is orange.
背景為橙色。
Now if I wanted to change the width and the height of this I could do this very easily just by just by doing this and just refreshing again.
現在,如果我想改變寬度和高度,只需這樣做並再次刷新即可,非常簡單。
And here we go.
我們開始吧。
And now it's smaller.
現在變小了。
So that's essentially how you start how you get started with the juice component class and including that in the juice audio processor editor.
這就是你如何開始使用 juice 組件類,並將其納入 juice 音頻處理器編輯器的基本方法。
Now the final thing that I'll show you is diving a little bit deeper into how the plug-in actually gets created.
現在,我要向你展示的最後一件事就是深入瞭解插件的實際創建過程。
So for people who want to really understand how does this process actually get started.
是以,對於那些想真正瞭解這一過程是如何開始的人來說。
What we can do is we can go back to our plug-in processor dot CPP.
我們可以做的是回到插件處理器點 CPP。
And there's actually a function in here called create editor.
實際上,這裡有一個名為創建編輯器的功能。
And what you're going to see is that this is that it creates a new audio plug-in audio processor editor which is what the name of this class is.
你將看到的是,它創建了一個新的音頻插件音頻處理器編輯器,這就是這個類的名字。
Right.
對
So that's that's where that's where this actually gets created.
所以,這才是真正的創造。
So if you look at the juice plug-in process in terms of how that actually what actually starts creating where where things start and what things get created and in what order.
是以,如果你看一下果汁插件的流程,就會發現它實際上是如何開始創建的,從哪裡開始創建,創建了哪些內容,創建的順序是怎樣的。
You'll see here that the audio processor gets created first and then it creates a new audio processor editor.
你會看到這裡首先創建了音頻處理器,然後創建了一個新的音頻處理器編輯器。
And that's and that's what that's what you see here.
這就是你在這裡看到的。
So if you didn't want it to have a plug-in window you could just you could just return it false.
是以,如果你不希望它有一個插件窗口,你可以直接返回 false。
But that just shows you that it's the audio processor that starts.
但這恰恰說明,啟動的是音頻處理器。
So it's the background audio processing that starts first and then it creates the visual aspect and does the connection points of that.
是以,它首先開始進行背景音頻處理,然後創建視覺方面,並完成其中的連接點。
So I hope that this was educational for you and that that you found it helpful.
是以,我希望這篇文章對你有教育意義,並對你有所幫助。
One thing that I should mention is that this is one of a number of ways that user interfaces can now be created using juice.
有一點我得提一下,這只是現在使用 juice 創建用戶界面的眾多方法之一。
I think that this is the easiest way to get started.
我認為這是最簡單的入門方法。
But once you get a little bit more advanced there are actually ways that you can create user interfaces using JavaScript as well.
不過,一旦你掌握了一些更高級的方法,其實也可以使用 JavaScript 創建用戶界面。
But that's a little bit more complex to set up and get running.
但要設置和運行起來就有點複雜了。
But we'll go through that a little bit later.
不過,我們稍後再討論這個問題。
So I hope you enjoy this.
希望你們喜歡。
If you liked it, please give it a like and subscribe to our channel and I will see you next time.
如果您喜歡,請點贊並訂閱我們的頻道,我們下次再見。
Happy coding.
快樂編碼