自定义容器
在创建应用时,您可能需要一个在 TouchGFX 中包含的标准控件集合中找不到的控件。
一种创建自定义控件的方法是使用自定义容器。 自定义容器是一个包含其他现有控件的对象,它组合了这些控件的视觉表现和行为。 它与传统的复合设计模式并无不同,我们也将包含的控件称为容器的子容器。
自定义容器的绘制性能通常会很高。 它会利用TouchGFX的底层绘图机制,并确定容器的哪些部分和子容器需要自动重新绘制。 这意味着在使用容器时无需担心绘图性能。
但是,有时候可能需要减少控件的空间占用量,在这种情况下,更高级的自定义控件方法可能更合适。
在TouchGFX Designer中
如果您需要在TouchGFX Designer中创建和使用自定义容器,我们在下面的视频中提供了如何在项目中使用它们的通俗介绍:
复合自定义容器
可以创建由其他自定义容器组成的自定义容器。 这可能是一种用更小的组件创建组件的有效方式。 为此,您可以添加在“控件”菜单中找到的已定义自定义容器的实例:
请注意,TouchGFX Designer将帮助您避免插入会导致循环引用的实例,如向自身定义添加自定义容器实例:
自定义触发条件和操作
自定义容器的一个强大之处是能够指定自定义触发条件(回调)和自定义操作(方法)。 这意味着您可以为自定义容器定义整体行为,使之不再只是控件的可重复使用集合,还可以与应用的其余部分通信。
Further reading
在代码中
在本节中我们将在代码中创建一个自定义容器。 步骤如下:
- 创建继承touchgfx::Container类的类
- 将容器的所有子容器声明为成员变量
- 设置容器的宽度和高度
- 设置每个子容器
- 按正确顺序将每个子容器添加到层次结构中
- 通过方法和回调实现需要的行为
我们将从头开始,基于代码进行构建,直至得到一个简单的全功能自定义容器。
创建继承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()
{
}
通过方法和回调实现需要的行为
为了向自定义容器中添加一些行为,我们可以在MyCustomContainer.hpp
中定义一些方法和回调。 在本例中,我们定义了方法doSomething()
,其唯一目的是发送回调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;
};
然后,为了向方法和回调添加行为,在MyCustomContainer.cpp
文件中实现它们。 对于这个简单的表面级示例,我们将只发送somethingHappened
回调,但您可以视需要进行自定义:
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();
}