教程4:建立具有自訂行為的滾輪。
在本教程中,您將學習如何建立和設定兩個小工具:自訂容器和滾輪。 自訂容器小工具可讓使用者組合多個其他小工具來建立新的小工具,並為自訂容器中的小工具新增特定行為。 滾輪是用來建立可捲動功能表的小工具,功能表是由多個可選項目組成。 本教程將展示如何建立使用者程式碼,以利修改小工具的行為。
這次我們將使用較大的螢幕,因此用800 x 480像素的解析度(如STM32F469探索套件)為開發板啟動新專案,或者也可以直接使用模擬器。
如需自訂容器和滾輪的詳細資訊,請參閱自訂容器和滾輪這兩個頁面。
本教程使用的圖形可從此連結下載。 將資產下的images資料夾中的檔案解壓縮,就本教程中使用的專案而言,路徑為MyApplication2\assets\images。
第1步:建立自訂容器
Similar to step 1 in tutorial 2, start by creating a new project with TouchGFX Designer. This time when the new project is ready, change from the screens tab in TouchGFX Designer to the Container tab (1).
用於建立自訂容器的分頁與「螢幕」分頁類似,以與建立新螢幕相同的方式建立新自訂容器。 在建立自訂容器後,可以為其新增小工具,並且可以變更自訂容器的大小和名稱。
在「自訂容器」分頁中,使用「+」按鈕 (1) 建立新自訂容器,將其重新命名為「MenuElement」(2),並將寬度變更為390、高度變更為70 (3)。
將小工具新增至自訂容器
在建立自訂容器並設定其屬性後,可以將小工具新增至自訂容器。 本教程中的自訂容器將包含一張圖像和一個使用萬用字元的文字區域:
Further reading
按照以下方式插入兩個小工具:
小工具 | 屬性 |
---|---|
Image |
|
TextArea |
|
將自訂容器新增至螢幕
回到「螢幕」分頁,現在可以在自訂容器下的小工具功能表中選擇「MenuElement」(1)。 放置一個黑色方塊作為背景,並將建立的幾個自訂容器新增到畫布上。 請注意,您可以在螢幕上自由移動插入的容器。 客製容器將顯示為左側「小工具」清單中的一個元素 (2)。
第2步:建立滾輪
在教程4的這一步中,我們將使用第1步中建立的自訂容器「MenuElement」來建立滾輪。 如第1步中所述,滾輪用於建立包含多個可選項目的可捲動功能表。 在滾動時,滾輪中的選項會自動更新;當選中一個選項時,該選項會突出顯示。
選擇要作為「選項範本」的自訂容器,將選項新增至滾輪。 「選項範本」的概念是使用自訂容器中的小工具作為滾輪中選項的基礎,並在執行階段使用使用者程式碼更新選項中的小工具。
建立滾輪
在建立滾輪前,移除螢幕上已插入的自訂容器,僅留下黑色方塊作為背景。 在「容器」部分下的小工具功能表中選擇「Scroll Wheel」(1)。 建立一個滾輪,將位置屬性設定為X = 208、Y = 45和H = 390,並將名稱變更為「scrollWheel」。
將選項新增至滾輪
使用滾輪屬性「選項範本」下的下拉式清單,選擇第1步中建立的「MenuElement」作為「選項範本」(1)。 滾輪中的選項數目也在「選項範本」下設定。 將其設定為20項。 由於滾輪會突出顯示選中項目,因此設定屬性「清單外觀」下的「選中項目偏移量」(2) 來設定選中項目在UI上的位置。 我們希望選中項目位於滾輪的中間,因此將「選中項目偏移量」設定為 (390-70)/2 = 160。
為了突出顯示「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步:將使用者程式碼新增至滾輪
With the Scroll Wheel, "scrollWheel", created and configured in TouchGFX Designer, this step will create the logic, via user code, that updates the items in "scrollWheel", so they display different graphics based on the position of the item in the wheel. 因此,這一步將整合TouchGFX Designer產生的程式碼和使用者程式碼。 關於整合TouchGFX Designer產生的程式碼和使用者程式碼的詳細說明,可以在程式碼結構頁面上找到。
變更MenuElement中的圖像和文字
由於滾輪中的選項是以第1步中建立的自訂容器「MenuElement」為基礎,因此需將用於變更圖示和更新萬用字元的使用者程式碼新增至「MenuElement」。 When a Custom Container is created in TouchGFX Designer it generates a .hpp and .cpp file with the same name as the Custom Container. 使用者程式碼應於這些檔案中整合。 在應用範例中針對「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」新增至「預設」字體排印的「萬用字元範圍」。
Press F4 to have the files generated by 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的內容後,下一件要做的事是新增用於更新滾輪中選項的程式碼。
更新滾輪中的選項
When creating a Scroll Wheel, TouchGFX Designer generates a virtual function in the Screen base class which is called each time a new item in the Scroll Wheel becomes visible. 在使用者程式碼中覆寫此函數將使程式碼能夠與滾輪中的選項互動。
函數名稱是滾輪名稱 + 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到此結束。