跳轉到主要內容

自訂容器

在創建應用時,您可能需要一個在TouchGFX的標準小部件集合中沒有的小部件。

一種創建自己的小部件的方法是使用自訂容器。 自訂容器是一個包含其他現有小部件的物件,它組合了這些小部件的視覺表現和行為。 它與傳統的複合設計模式並無不同,我們也將包含的小部件稱為容器的子容器。

自訂容器的繪製性能通常會很高。 它會利用TouchGFX的底層繪圖機制,並確定容器的哪些部分和子容器需要自動重新繪製。 這意味著在使用容器時無需擔心繪圖性能。

但是,有時候可能需要減少小部件的空間占用量,在這種情況下,更高級的自訂小部件方法可能更合適。

TouchGFX Designer中

如果您需要在TouchGFX Designer中創建和使用自訂容器,我們在下面的影片中提供了如何在專案中使用它們的綜合介紹:

複合自訂容器

可以創建由其他自訂容器組成的自訂容器。 這可能是一種用更小的元件創建元件的有效方式。 為此,您可以添加在“Widgets ”功能表中找到的已定義自訂容器的實例:

插入自訂容器的實例

請注意,TouchGFX Designer將幫助您避免插入會導致迴圈引用的實例,如向自身定義添加自訂容器實例:

潛在迴圈引用導致無法插入實例

自訂觸發條件和操作

自訂容器的一個強大之處是能夠指定自訂觸發條件(callbacks)和自訂操作(methods)。 這意味著您可以為自訂容器定義整體行為,使之不再只是小部件的可重複使用集合,還可以與應用程式的其餘部分通信。

Further reading
請閱讀自訂觸發條件和操作一節中關於此功能的更多內容。

程式碼中

自訂容器的一個強大之處是能夠指定自訂觸發條件(callbacks)和自訂操作(methods)。 這意味著您可以為自訂容器定義整體行為,使之不再只是小部件的可重複使用集合,還可以與應用程式的其餘部分通信。

  • 創建擴展touchgfx::Container類的類
  • 將容器的所有子容器宣告為成員變數
  • 設置容器的寬度和高度
  • 設置每個子容器
  • 按正確順序將每個子容器添加到層次結構中
  • 通過methods和callbacks實現需要的行為

我們將從頭開始,基於程式碼進行構建,直至得到一個簡單的全功能自訂容器。

創建擴展touchgfx::Container類的類

先用以下程式碼創建MyCustomContainer.hpp標頭檔。 使用C++繼承來訪問touchgfx::Container的方法和成員(請記得包含標頭檔Container.hpp):

MyCustomContainer.hpp
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/containers/Container.hpp>

class MyCustomContainer : public touchgfx::Container
{
public:
MyCustomContainer();
virtual ~MyCustomContainer() {}
virtual void initialize();

protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}

private:

};

將容器的所有子容器宣告為成員變數

在標頭檔中宣告自訂容器將要包含的小部件。 在本例中,我們將只添加一個方框myBox和一個按鈕myButton

MyCustomContainer.hpp
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/containers/Container.hpp>

class MyCustomContainer : public touchgfx::Container
{
public:
MyCustomContainer();
virtual ~MyCustomContainer() {}
virtual void initialize();

protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}

/*
* Member Declarations
*/
touchgfx::Box myBox;
touchgfx::Button myButton;

private:

};

設置容器的寬度和高度

創建cpp文件MyCustomContainer.cpp,其中包含我們剛剛創建的標頭檔。 使用構造函數中的setWidth()setHeight()方法,為自訂容器設置任何大小:

MyCustomContainer.cpp
#include <gui/include/containers/MyCustomContainer.hpp>

MyCustomContainer::MyCustomContainer()
{
setWidth(250);
setHeight(250);
}

void MyCustomContainer::initialize()
{

}

設置每個子容器

現在,需要在構造函數中設置每個小部件的屬性:

MyCustomContainer.cpp
#include <gui/include/containers/MyCustomContainer.hpp>

MyCustomContainer::MyCustomContainer()
{
setWidth(250);
setHeight(250);

myBox.setPosition(0, 0, 250, 250);
myBox.setColor(touchgfx::Color::getColorFromRGB(255, 255, 255));

myButton.setXY(40, 95);
myButton.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_ID), touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_PRESSED_ID));
}

void MyCustomContainer::initialize()
{

}

按正確順序將每個子容器添加到層次結構中

使用構造函數中的add()方法,將小部件添加為自訂容器的子容器:

MyCustomContainer.cpp
#include <gui/containers/MyCustomContainer.hpp>

MyCustomContainer::MyCustomContainer()
{
setWidth(250);
setHeight(250);

myBox.setPosition(0, 0, 250, 250);
myBox.setColor(touchgfx::Color::getColorFromRGB(255, 255, 255));

myButton.setXY(40, 95);
myButton.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_ID), touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_PRESSED_ID));

add(myBox);
add(myButton);
}

void MyCustomContainer::initialize()
{

}

通過methods和callbacks實現需要的行為

為了向自訂容器中添加一些行為,我們可以在MyCustomContainer.hpp中定義一些methods和callbacks。 在本例中,我們定義了方法doSomething(),其唯一目的是發送callback somethingHappened

MyCustomContainer.hpp
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/containers/Container.hpp>

class MyCustomContainer : public touchgfx::Container
{
public:
MyCustomContainerBase();
virtual ~MyCustomContainerBase() {}
virtual void initialize();

/*
* Callback Setters
*/
void setSomethingHappenedCallback(touchgfx::GenericCallback<>& callback)
{
somethingHappenedCallback = &callback;
}

/*
* Methods
*/
virtual void doSomething();

protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}

/*
* Callback Emitters
*/
virtual void emitSomethingHappenedCallback()
{
if (somethingHappenedCallback && somethingHappenedCallback->isValid())
{
somethingHappenedCallback->execute();
}
}

/*
* Member Declarations
*/
touchgfx::Box myBox;
touchgfx::Button myButton;

private:

/*
* Callback Declarations
*/
touchgfx::GenericCallback<>* somethingHappenedCallback;

};

然後,為了向method 和callback添加行為,在MyCustomContainer.cpp檔中實現它們。 對於這個簡單的表面級範例,我們將只發送somethingHappenedcallback,但您可以視需要進行自訂:

MyCustomContainer.cpp
#include <gui/containers/MyCustomContainer.hpp>

MyCustomContainer::MyCustomContainer()
{
setWidth(250);
setHeight(250);

myBox.setPosition(0, 0, 250, 250);
myBox.setColor(touchgfx::Color::getColorFromRGB(255, 255, 255));

myButton.setXY(40, 95);
myButton.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_ID), touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_PRESSED_ID));

add(myBox);
add(myButton);
}

void MyCustomContainer::initialize()
{

}

void MyCustomContainer::doSomething()
{
MyCustomContainer::emitSomethingHappenedCallback();
}
Further reading
關於如何創建和使用自訂容器的更多具體範例,請參考教程4:創建具有自訂行為的滾輪