你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32U599】5.聊聊手表菜单

[复制链接]
奇迹 发布时间:2023-12-29 22:01

第2篇被日天兄吐槽太简单,这次就来详细讲一下。

首先准备好需要显示的图片素材,导入软件里面。

微信截图_20231229215342.png

TouchGFX默认使用的字体是不支持中文的,这里我们新建一个楷体的字体。

微信截图_20231229215423.png

创建自定义的文字内容,用在代码里面调用(这种相当于自定义的小字库)。

微信截图_20231229215403.png

新建一个自定义控件,这个根据自己的喜好来就行。

微信截图_20231229215648.png

创建一个scrollWheel控件(scrollWheel与scrollList比较接近。区别在于,scrollList:当滑动到某一个子单元时,触发回调。scrollWheel:当点击某一个子单元时,触发回调,这里我们想实现一个点击进入的手表菜单,所以需要使用scrollWheel),具体配置可以参见截图,配置项还是很好理解的。

微信截图_20231229215737.png

生成代码,启动vs,准备编写代码。

先运行一下仿真看看。

微信截图_20231229221640.png

存在两个问题,第一、子单元都是显示的闹钟。第二、不是圆弧显示。我们一个个解决。

实现自定义子单元显示

编写代码

MenuElement.hpp

#ifndef MENUELEMENT_HPP
#define MENUELEMENT_HPP

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

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

    virtual void initialize();

    void setNumber(int no);
protected:
};

#endif // MENUELEMENT_HPP

MenuElement.cpp

#include <gui/containers/MenuElement.hpp>

MenuElement::MenuElement()
{

}

void MenuElement::initialize()
{
    MenuElementBase::initialize();
}

void MenuElement::setNumber(int no)
{
    //Unicode::itoa(no, textBuffer, TEXT_SIZE, 10);
    switch (no)
    {
    case 0:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_COMMUNICATION_CALL_80_80_00FF00_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_PHONE));
        break;
    case 1:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_COMMUNICATION_CHAT_80_80_00940F_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_INFO));
        break;
    case 2:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_COMMUNICATION_QR_CODE_SCANNER_80_80_FFFFFF_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_QR));
        break;
    case 3:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_DEVICE_ACCESS_ALARM_80_80_0000FF_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_ALARM));
        break;
    case 4:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_IMAGE_MUSIC_NOTE_80_80_FF0000_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_MUSIC));
        break;
    case 5:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_SOCIAL_SWITCH_ACCOUNT_80_80_00FFB3_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_BOOK));
        break;
    case 6:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_MAPS_DIRECTIONS_RUN_80_80_9000FF_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_MOTION));
        break;
    case 7:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_ACTION_SETTINGS_80_80_FFEE00_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_SET));
        break;
    default:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_COMMUNICATION_CALL_80_80_00FF00_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_PHONE));
        break;
    }
}

因为每一个子控件都是独立的,如果想在界面里面对自定义控件进行操作,自定义控件需要提供一个对外的接口。 我们创建了一个叫void setNumber(int no);的函数,只要输入对应的索引就能控制控件显示不同的元素。

menuView.hpp

#ifndef MENUVIEW_HPP
#define MENUVIEW_HPP

#include <gui_generated/menu_screen/menuViewBase.hpp>
#include <gui/menu_screen/menuPresenter.hpp>

class menuView : public menuViewBase
{
public:
    menuView();
    virtual ~menuView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    virtual void scrollWheelUpdateItem(MenuElement& item, int16_t itemIndex);
protected:
};

#endif // MENUVIEW_HPP

menuView.cpp

#include <gui/menu_screen/menuView.hpp>

menuView::menuView()
{

}

void menuView::setupScreen()
{
    menuViewBase::setupScreen();
}

void menuView::tearDownScreen()
{
    menuViewBase::tearDownScreen();
}

void menuView::scrollWheelUpdateItem(MenuElement& item, int16_t itemIndex)
{
    item.setNumber(itemIndex);
}

主要是通过scrollWheelUpdateItem调用了item.setNumber(itemIndex)进行控制显示。scrollWheelUpdateItem函数由TouchGFX设计器自动生成,具体可见menuViewBase.cpp文件。

跑一下仿真看看。

微信截图_20231229224956.png

已经可以正常显示了。

实现圆弧显示

不罗嗦,直接上代码

MenuElement.hpp

#ifndef MENUELEMENT_HPP
#define MENUELEMENT_HPP

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

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

    virtual void initialize();

    void setNumber(int no);
    void offset(int16_t x);
    virtual void setY(int16_t y);
protected:
};

#endif // MENUELEMENT_HPP

MenuElement.cpp

#include <gui/containers/MenuElement.hpp>

MenuElement::MenuElement()
{

}

void MenuElement::initialize()
{
    MenuElementBase::initialize();
}

void MenuElement::setNumber(int no)
{
    switch (no)
    {
    case 0:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_COMMUNICATION_CALL_80_80_00FF00_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_PHONE));
        break;
    case 1:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_COMMUNICATION_CHAT_80_80_00940F_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_INFO));
        break;
    case 2:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_COMMUNICATION_QR_CODE_SCANNER_80_80_FFFFFF_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_QR));
        break;
    case 3:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_DEVICE_ACCESS_ALARM_80_80_0000FF_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_ALARM));
        break;
    case 4:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_IMAGE_MUSIC_NOTE_80_80_FF0000_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_MUSIC));
        break;
    case 5:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_SOCIAL_SWITCH_ACCOUNT_80_80_00FFB3_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_BOOK));
        break;
    case 6:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_MAPS_DIRECTIONS_RUN_80_80_9000FF_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_MOTION));
        break;
    case 7:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_ACTION_SETTINGS_80_80_FFEE00_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_SET));
        break;
    default:
        icon.setBitmap(Bitmap(BITMAP_ICON_THEME_IMAGES_COMMUNICATION_CALL_80_80_00FF00_SVG_ID));
        text.setTypedText(touchgfx::TypedText(T_MENU_PHONE));
        break;
    }
}

void MenuElement::offset(int16_t x)
{
    icon.setX(30 + x);
    text.setX(120 + x);
}

void MenuElement::setY(int16_t y)
{
    MenuElementBase::setY(y);

    const int circleRadius = 300;
    y = y + getHeight() / 2 - 480 / 2;
    float x_f = circleRadius - sqrtf((float)((circleRadius * circleRadius) - (y * y)));
    int16_t x = (int16_t)(x_f + 0.5f);

    offset(x);
}

首先解释一下为啥重载setY,这次的代码菜单是上下滑动的,每一次滑动的时候都会改变控件Y的位置。

因为TouchGFX代码本身是不开源的,我们并不清楚scrollWheel是如何实现的setY,所以希望在原本的代码基础上,加入我们自定义的代码,所以调用了MenuElementBase::setY(y);这样就能保留原始实现。

接下来的代码就没啥好讲的了,就是通过不同的y计算出x在的位置,这样就能实现圆弧一样的滑动。

跑一下仿真,看看是否正常。

微信截图_20231229231611.png

效果不错,下到单片机试试。

37e607ba23a8dc7211c68a911e0d5328.gif

收工。

收藏 评论2 发布时间:2023-12-29 22:01

举报

2个回答
lospring 回答时间:2023-12-29 23:58:21

不错的教学,真是学习到了,谢谢分享

小样爱捣鼓 回答时间:2024-1-2 09:04:44

谢谢分享!

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版