iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0

按:下筆此刻,JUCE 版本為 6.1,此系列文章皆以此版為準。

這篇說明加入 UI 控制項的其中一個方法。Projucer 建出來的 GUI Application 專案長這樣:

紅框對應到程式碼中的 MainComponent 類別如下。(為了閱讀舒適,程式碼做了些許調整):

class MainComponent  : public juce::Component
{
public:
  MainComponent()
  {
    setSize (600, 400);
  }
  
  ~MainComponent() = default;

  void paint (juce::Graphics&) override
  {
    g.fillAll(getLookAndFeel().findColour(juce::ResizableWindow::backgroundColourId));

    g.setFont (juce::Font (16.0f));
    g.setColour (juce::Colours::white);
    g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true);
  }
  
  void resized() override
  {
  }

private:

  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};

paint() 負責畫出視窗中間的 "Hello World!",改成文字按鈕會用到 juce::TextButton 類別。步驟如下:

  1. 刪除畫 "Hello World!" 的程式碼
  2. 增加一個 TextButton 物件,命名為 google_button_
  3. MainComponent 建構式中
    1. google_button_ 按鈕的文字設為 "Google!"
    2. 使用 onClick 設定其行為:以系統預設瀏覽器開啟 "https://www.google.com"
  4. TextButton 物件加到 MainComponent 中,並將其屬性設為 Visible。(使用 addAndMakeVisible 函數)
  5. MainComponent::resized 函數中,設定 TextButton 的大小。上下左右各內縮了 10px,讓按鈕的樣子更明顯。改動後的程式碼如下:
class MainComponent  : public juce::Component
{
public:
  MainComponent() :
    google_button_("Google!")
  {
    setSize (600, 400);
    
    google_button_.onClick = []()
    {
      juce::URL google("https://www.google.com");
      google.launchInDefaultBrowser();
    };
    
    addAndMakeVisible(google_button_);
  }
  
  ~MainComponent() = default;

  void paint (juce::Graphics&) override
  {
    g.fillAll(getLookAndFeel().findColour(juce::ResizableWindow::backgroundColourId));
  }
  
  void resized() override
  {
    google_button_.setBounds(getLocalBounds().reduced(10, 10));
  }

private:

  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};

修改後的視窗:

滑鼠點擊 Google! 按鈕開啟 Google 首頁:

細部分解

前篇提到 JUCE UI 架構下,所有控制項皆繼承自 Component 類別,這個基礎類別的行為之一是可以「容納」其他 Component 物件,例如此例中的 google_button_ 物件。

上面的範例中,使用 addAndMakeVisible 函數把 google_button_ 物件加到 MainComponent 中。

可以把 MainComponent 看成容器,內含了另一個 Component 物件(google_button_),google_button_ 物件即為 MainComponent 的 Child Component。

查看 addAndMakeVisible 實作,其實是兩個動作組成:

  1. 將 Child Component 屬性設成 Visible
  2. 將 Child Component 納入,並指定其 Z-Order(以後再說明)
void Component::addAndMakeVisible (Component& child, int zOrder)
{
    child.setVisible (true);
    addChildComponent (child, zOrder);
}

上述範例使用了 TextButton 中的 onClick,其型別為 std::function<void()>。這是在 JUCE 採用了 C++11 規格後,讓開發者可以使用 Lambda 來設計按鈕的邏輯。

JUCE 開發時 C++11 還沒發生,許多組件,例如 Smart Pointer 必須手工打造。支援 C++11/14 標準後,JUCE code base 漸漸改用 C++ 標準函式庫的組件,這是好的進展。理由為何,以後再談。


上一篇
Day 10:Component, Component, Component
下一篇
Day 12:擺放控制項(一)
系列文
JUCE 入門 @ 跨平台應用程式開發使用 C++29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言