跳轉到主要內容

教程4:建立具有自訂行為的滾輪。

在本教程中,您將學習如何建立和設定兩個小工具:自訂容器和滾輪。 自訂容器小工具可讓使用者組合多個其他小工具來建立新的小工具,並為自訂容器中的小工具新增特定行為。 滾輪是用來建立可捲動功能表的小工具,功能表是由多個可選項目組成。 本教程將展示如何建立使用者程式碼,以利修改小工具的行為。

這次我們將使用較大的螢幕,因此用800 x 480像素的解析度(如STM32F469探索套件)為開發板啟動新專案,或者也可以直接使用模擬器。

如需自訂容器和滾輪的詳細資訊,請參閱自訂容器滾輪這兩個頁面。

本教程使用的圖形可從此連結下載。 將資產下的images資料夾中的檔案解壓縮,就本教程中使用的專案而言,路徑為MyApplication2\assets\images。

第1步:建立自訂容器

與教程2中的第1步類似,首先用TouchGFX Designer建立新專案。 這一次,當新專案就緒時,在TouchGFX Designer中從「螢幕」分頁切換到「容器」分頁(1)。

1

選擇「自動容器」功能表

用於建立自訂容器的分頁與「螢幕」分頁類似,以與建立新螢幕相同的方式建立新自訂容器。 在建立自訂容器後,可以為其新增小工具,並且可以變更自訂容器的大小和名稱。

在「自訂容器」分頁中,使用「+」按鈕 (1) 建立新自訂容器,將其重新命名為「MenuElement」(2),並將寬度變更為390、高度變更為70 (3)。

123

建立自訂容器並設定其屬性

將小工具新增至自訂容器

在建立自訂容器並設定其屬性後,可以將小工具新增至自訂容器。 本教程中的自訂容器將包含一張圖像和一個使用萬用字元的文字區域:

Further reading
如需深入了解如何使用含有萬用字元的文字,請閱讀文字和字型頁面的萬用字元部分。

按照以下方式插入兩個小工具:

小工具屬性
Image
  • 名稱:icon
  • 圖像:icon00.png
  • 位置:
    • X:34
    • Y:17
TextArea
  • 名稱:text
  • 位置:
    • X:93、Y:23
  • 文字:
    • 文字:Menu Element <value>
    • 萬用字元1:
      • 初始值:00
      • 緩衝區大小:3
      • 使用萬用字元緩衝區:是
    • 字體排印:20px
    • 對齊:置左
  • 外觀:
    • 顏色:#FFFFFFFF

將內容新增到自訂容器(已選擇TextArea)

將自訂容器新增至螢幕

回到「螢幕」分頁,現在可以在自訂容器下的小工具功能表中選擇「MenuElement」(1)。 放置一個黑色方塊作為背景,並將建立的幾個自訂容器新增到畫布上。 請注意,您可以在螢幕上自由移動插入的容器。 客製容器將顯示為左側「小工具」清單中的一個元素 (2)。

12

在螢幕上將自訂容器作為小工具插入

第2步:建立滾輪

在教程4的這一步中,我們將使用第1步中建立的自訂容器「MenuElement」來建立滾輪。 如第1步中所述,滾輪用於建立包含多個可選項目的可捲動功能表。 在滾動時,滾輪中的選項會自動更新;當選中一個選項時,該選項會突出顯示。

選擇要作為「選項範本」的自訂容器,將選項新增至滾輪。 「選項範本」的概念是使用自訂容器中的小工具作為滾輪中選項的基礎,並在執行階段使用使用者程式碼更新選項中的小工具。

建立滾輪

在建立滾輪前,移除螢幕上已插入的自訂容器,僅留下黑色方塊作為背景。 在「容器」部分下的小工具功能表中選擇「Scroll Wheel」(1)。 建立一個滾輪,將位置屬性設定為X = 208、Y = 45和H = 390,並將名稱變更為「scrollWheel」。

1

插入滾輪並設定名稱和位置屬性

將選項新增至滾輪

使用滾輪屬性「選項範本」下的下拉式清單,選擇第1步中建立的「MenuElement」作為「選項範本」(1)。 滾輪中的選項數目也在「選項範本」下設定。 將其設定為20項。 由於滾輪會突出顯示選中項目,因此設定屬性「清單外觀」下的「選中項目偏移量」(2) 來設定選中項目在UI上的位置。 我們希望選中項目位於滾輪的中間,因此將「選中項目偏移量」設定為 (390-70)/2 = 160。

12

將自訂容器新增至滾輪並調整其屬性

為了突出顯示「scrollWheel」的區域,使用第1步中下載的.zip檔中的兩張圖像background.png和overlay.png,並將它們作為圖像小工具新增至應用。 兩張圖像是背景,突出顯示「scrollWheel」的區域和一個覆蓋層,後者會在移動到「scrollWheel」的邊緣時隱藏「scrollWheel」中的選項。

圖像background.png的座標為X = 205和Y = 45,位於「scrollWheel」後方,因此在背景上方繪製「scrollWheel」中的選項。 overlay.png的座標為X = 0和Y = 0,位於「scrollWheel」上方,這表示在overlay.png下方繪製選項,以便隱藏overlay.png不透明部分的選項。

按下CTRL-B和CTRL-F鍵可以前後移動「小工具」清單中的小工具。

新增至有滾輪的螢幕中的圖形

我們只調整了「scrollWheel」的靜態屬性,尚未為其新增邏輯。 因此,執行應用將得到一個可捲動功能表,其中包含了20個外觀全部相同的選項。 在下一步中,我們將用使用者程式碼為「scrollWheel」新增邏輯,以便在執行階段更新滾輪中的選項。

第3步:將使用者程式碼新增至滾輪

我們已在TouchGFX Designer中建立並設定了滾輪「scrollWheel」,這一步將透過使用者程式碼建立邏輯,邏輯會更新「scrollWheel」中的選項,以便根據滾輪中選項的位置顯示不同圖形。 因此,這一步將整合TouchGFX Designer產生的程式碼和使用者程式碼。 關於整合TouchGFX Designer產生的程式碼和使用者程式碼的詳細說明,可以在程式碼結構頁面上找到。

變更MenuElement中的圖像和文字

由於滾輪中的選項是以第1步中建立的自訂容器「MenuElement」為基礎,因此需將用於變更圖示和更新萬用字元的使用者程式碼新增至「MenuElement」。 如果自訂容器是在TouchGFX Designer中建立的,則產生與自訂容器同名的.hpp和.cpp檔案。 使用者程式碼應於這些檔案中整合。 在應用範例中針對「MenuElement」產生的檔案位置如下:

MyApplication2\gui\include\gui\containers\MenuElement.hpp

MyApplication2\gui\src\containers\MenuElement.cpp

將函數setNumber(int no)新增至「MenuElement」後,「scrollWheel」中選項的文字和圖示即可供變更。 該函數使用變數no來決定Image小工具應顯示哪個圖示,並將TextArea小工具中的萬用字元變更為no值。

由於我們在TextArea中使用了數字0-9,因此還需要將範圍「0-9」新增至「預設」字體排印的「萬用字元範圍」。

按下F4鍵獲取TouchGFX Designer產生的檔案。

setNumber(int no)的宣告和實作是在MenuElement.hpp 中完成的,如下圖所示。

TouchGFX/gui/include/gui/containers/MenuElement.hpp
#ifndef MENUELEMENT_HPP
#define MENUELEMENT_HPP

#include <gui_generated/containers/MenuElementBase.hpp>
#include <images/BitmapDatabase.hpp>

class MenuElement : public MenuElementBase
{
public:
MenuElement();
virtual ~MenuElement() {}

virtual void initialize();

void setNumber(int no)
{
Unicode::itoa(no, textBuffer, TEXT_SIZE, 10);
switch (no % 7)
{
case 0:
icon.setBitmap(Bitmap(BITMAP_ICON00_ID));
break;
case 1:
icon.setBitmap(Bitmap(BITMAP_ICON01_ID));
break;
case 2:
icon.setBitmap(Bitmap(BITMAP_ICON02_ID));
break;
case 3:
icon.setBitmap(Bitmap(BITMAP_ICON03_ID));
break;
case 4:
icon.setBitmap(Bitmap(BITMAP_ICON04_ID));
break;
case 5:
icon.setBitmap(Bitmap(BITMAP_ICON05_ID));
break;
case 6:
icon.setBitmap(Bitmap(BITMAP_ICON06_ID));
break;
}
}
protected:
};

#endif // MENUELEMENT_HPP

程式碼使用BITMAP定義來參照專案中的圖像。 為了能夠使用這些圖像,必須像之前一樣包含檔案「images/BitmapDatabase.hpp」。

在新增程式碼更新MenuElement的內容後,下一件要做的事是新增用於更新滾輪中選項的程式碼。

更新滾輪中的選項

在建立滾輪時,TouchGFX Designer會在Screen基礎類別中產生虛擬函數,每當滾輪中的新選項變得可見時都會呼叫此函數。 在使用者程式碼中覆寫此函數將使程式碼能夠與滾輪中的選項互動。

函數名稱是滾輪名稱 + UpdatedItem。 就本教程而言,函數名稱為scrollWheelUpdateItem(MenuElement& item, int16_t itemIndex)

參數itemIndex是索引值,指示目前正在更新的選項,選項是對滾輪中目前可見的MenuElement實例的引用。 itemIndex指示正在更新的選項,為選項呼叫的setNumber()將根據itemIndex的值修改正在更新的選項的內容。 下面是用於更新滾輪選項的程式碼。

Screen1View.hpp
#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP

#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>

class Screen1View : public Screen1ViewBase
{
public:
Screen1View();
virtual ~Screen1View() {}
virtual void setupScreen();
virtual void tearDownScreen();
virtual void scrollWheelUpdateItem(MenuElement& item, int16_t itemIndex)
{
item.setNumber(itemIndex);
}
protected:
};

#endif // SCREEN1VIEW_HPP

現在執行應用的模擬器,結果顯示選項的文字包含其索引值,且圖示會隨顯示的選項而變化。 下圖顯示了用實作的程式碼執行模擬器的範例。

執行模擬器

第4步:將自訂行為新增至滾輪

在教程4的最後一步中,我們將為滾輪新增自訂行為,使其在滾動選項時以環形模式,即類似於錶盤的模式移動。

將自訂行為新增至MenuElement

讓滾輪以錶盤模式移動,是透過移動滾輪中每個可見選項的圖像和文字小工具的水平位置來實現。 為此,在MenuElement.hpp中覆寫「MenuElement」的函數setY()。 每次沿垂直方向移動自訂容器時,都會呼叫它的setY()函數,該函數用於在新位置重繪自訂容器。 透過覆寫setY(),在每次滾動滾輪時,還能夠在容器內部水平移動圖像和文字小工具。 下圖顯示了如何在MenuElement.hpp中實作新的setY()函數以及移動兩個小工具。 請注意,需將math.h包含在內。

MenuElement.hpp
#ifndef MENUELEMENT_HPP
#define MENUELEMENT_HPP

#include <gui_generated/containers/MenuElementBase.hpp>
#include <images/BitmapDatabase.hpp>
#include <math.h>

class MenuElement : public MenuElementBase
{
public:
MenuElement();
virtual ~MenuElement() {}

virtual void initialize();

//Adjusts the position of the text and the icon, based in the calculated offset(x)
void offset(int16_t x)
{
icon.setX(30 + x);
text.setX(80 + x);
}

//The new declaration and implementation of the setY() function
virtual void setY(int16_t y)
{
//set Y as normal
MenuElementBase::setY(y);

const int circleRadius = 250;

//center around middle of background
y = y + getHeight() / 2 - 390 /2;

//calculate x
float x_f = circleRadius - sqrtf((float)((circleRadius * circleRadius) - (y * y)));
int16_t x = (int16_t)(x_f + 0.5f);

offset(x);
}

...

實作新的setY()函數後,執行模擬器,結果顯示滾輪以錶盤模式(與覆蓋層的曲線對齊)移動。

執行模擬器

教程4到此結束。

Further reading
為了深入學習教程中使用的相關概念,下面的章節將討論您已使用的一些概念: