教程4:創建具有自訂行為的滾輪。
在本教程中,您將學習如何創建和配置兩個小部件 - 自訂容器和滾輪。 自訂容器小部件使使用者能夠通過組合多個其他小部件來創建新的小部件,並為自訂容器中的小部件添加特定行為。 滾輪是用來創建可捲動功能表的小部件,菜單由多個可選項群組成。 本教程將展示如何創建用戶程式碼以便修改小部件的行為。
這次我們將使用較大的螢幕,因此用800 x 480像素的解析度為開發板啟動新專案(如STM32F469探索套件),或者也可以直接使用模擬器。
關於自訂容器和滾輪的更多資訊,可以在“自訂容器”和“滾輪”頁面上找到。
本教程使用的圖形可從此連結下載。 將資產下的images資料夾中的檔案解壓縮,就本教程中使用的專案而言,路徑為MyApplication2\assets\images。
第1步:創建自訂容器
與教程2中的第1步類似,首先用TouchGFX Designer新建專案。 這一次,當新專案就緒時,在TouchGFX Designer中從“screens”選項卡切換到“Container”選項卡 (1)。
用於創建自訂容器的選項卡與“Screens”選項卡類似,以與新建螢幕相同的方式新建自訂容器。 在創建自訂容器後,可以為其添加小部件,並且可以修改自訂容器的大小和名稱。
在“自訂容器”選項卡上,使用“+”按鈕 (1) 新建一個自訂容器,將其重命名為“MenuElement”(2),並將寬度修改為390、高度修改為70 (3)。
將小部件添加到自訂容器
在創建自訂容器並設置其屬性後,可以將小部件添加到自訂容器。 本教程中的自訂容器將包含一張圖像和一個使用萬用字元的文字區:
Further reading
按照以下方式插入兩個小部件:
小部件 | 屬性 |
---|---|
圖像 |
|
TextArea |
|
將自訂容器添加到螢幕
回到“螢幕”選項卡,現在可以在自訂容器下的控制項功能表中選擇“MenuElement”(1)。 放置一個黑色方塊作為背景,並將創建的幾個客製容器添加到畫布上。 請注意,您可以在螢幕上自由地移動插入的容器。 客製容器將顯示為左側“小工具”清單中的一個元素 (2)。
第2步:創建滾輪
在教程4的這一步中,我們將使用第1步中創建的自訂容器“MenuElement”創建滾輪。 如第1步中所述,滾輪用於創建包含多個可選項的可捲動功能表。 在滾動時,滾輪中的選項會自動更新;當選中一個選項時,該選項會突出顯示。
通過選擇要用作“選項範本”的自訂容器,將選項添加到滾輪。 “選項範本”的概念是使用自訂容器中的小部件作為滾輪中選項的基礎,並在執行時間使用使用者程式碼更新選項中的小部件。
創建滾輪
在創建滾輪前,刪除螢幕上已插入的自訂容器,僅留下黑色方塊作為背景。 在“Containers ”區下的小部件功能表中選擇“Scroll Wheel”(1)。 創建一個滾輪,將位置屬性設置為X = 208、Y = 45和H = 390,並將名稱修改為“scrollWheel”。
將選項添加到滾輪
使用滾輪屬性“Item Template”下的下拉清單,選擇第1步中創建的“MenuElement”作為“選項範本”(1)。 滾輪中的選項數也在“選項範本”下設置。 將其設置為20項。 由於滾輪會突出顯示選中項,因此通過設置屬性“清單外觀”下的“選中項偏移量”(2) 來設置選中項在UI上的位置。 我們希望選中項位於滾輪的中間,因此將“Selected Item Offset”設置為 (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步:將用戶程式碼添加到滾輪
我們已在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
來決定應顯示哪個圖示和圖像小部件,並將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 <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定義來參照專案中的圖像。 為了能夠使用這些圖像,必須像之前一樣包含檔案“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 <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到此結束。