iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0

視窗應用軟體開發其中一個環節是版面設計。JUCE 有幾種控制版面的作法,本篇介紹如何使用 juce::Rectangle 類別來安排控制項。

下圖為設計目標:

  • 第一排有三個大小相同的按鈕
  • 第二排是文字輸入框,與第一排的按鈕對齊
  • 第三排是兩張大小不同的圖片

首先加上必要的 TextButton。為了說明方便,程式採「作業式」寫法,在 MainComponent 加上以下三個 TextButton 物件:

  juce::TextButton google_button_;
  juce::TextButton duckduckgo_button_;
  juce::TextButton bing_button_;

接著在 MainComponent 建構式初始化上述物件,並將其加入 MainComponent

class MainComponent  : public juce::Component
{
public:
  MainComponent() :
    google_button_("Google!"),
    duckduckgo_button_("DuckDuckGo"),
    bing_button_("Bing")
  {
    setSize (600, 400);

    addAndMakeVisible(google_button_);
    addAndMakeVisible(duckduckgo_button_);
    addAndMakeVisible(bing_button_);    
  }
};

然後替每個按鈕加上行為。在 MainComponent 建構式內,採用「作業式」複製貼上大法:

  google_button_.onClick = []()
  {
    juce::URL google("https://www.google.com");
    google.launchInDefaultBrowser();
  };
    
  duckduckgo_button_.onClick = []()
  {
    juce::URL duckduckgo("https://duckduckgo.com/");
    duckduckgo.launchInDefaultBrowser();
  };

  bing_button_.onClick = []()
  {
    juce::URL bing("https://www.bing.com/");
    bing.launchInDefaultBrowser();
  };

接下來是重頭戲,要在 MainComponent::resized 函數裡安排各個控制項的「大小」以及「位置」。本篇使用 juce::Rectangle 來切版。

首先定義兩個常數,一個表示按鈕寬度(kButtonWidth);一個表示每一行之間的間隔(kRowDistance)。

getLocalBounds 函數回傳 Rectangle,代表 MainComponent 的可用大小,接著呼叫 reduced 函數,將上下左右分別內縮 (20, 10)。

取得內縮後的 Rectangle 後,利用 removeFromTop 函數取得整個 MainComponent 高度的 20%。

void MainComponent::resized()
{
  const int kButtonWidth = 150;
  const int kRowDistance = 10;
  const int kButtonDistance = 20;

  auto bounds = getLocalBounds().reduced(20, 10);
  auto first_row = bounds.removeFromTop(getLocalBounds().getHeight() * 0.2);
}

取得第一列的 Rectangle 後,開始切三個按鈕的位置。

void MainComponent::resized()
{
  auto google_bounds = first_row.removeFromLeft(kButtonWidth);
  google_button_.setBounds(google_bounds);
  
  first_row.removeFromLeft(kButtonDistance);
  auto duckduckgo_bounds = first_row.removeFromLeft(kButtonWidth);
  duckduckgo_button_.setBounds(duckduckgo_bounds);
  
  first_row.removeFromLeft(kButtonDistance);
  auto bing_bounds = first_row.removeFromLeft(kButtonWidth);
  bing_button_.setBounds(bing_bounds);
}

到目前為止,離我們的設計目標還有點距離,需要進一步調整。

延伸閱讀

juce::Rectangle 的詳細用法,我建議閱讀以下兩篇:


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

尚未有邦友留言

立即登入留言