不止是进度条:深入PiXSingleGUI的TpSlideProgressBar组件架构设计
组件运行效果展示
TpSlideProgressBar 组件概述
TpSlideProgressBar
是TinyPiXOS系统中专门用于交互式进度控制的GUI组件,属于PiXSingleGUI库的标准化控件之一。该组件继承自TpChildWidget基类,遵循PiXSingleGUI的统一架构设计。
核心架构设计
继承关系与基类依赖
TpSlideProgressBar继承自TpChildWidget,这确保了它具备完整的GUI组件能力,包括事件处理、渲染管理和生命周期控制。
数据结构设计
组件采用PIMPL(Private Implementation)设计模式,通过TpSlideProgressBarData结构体封装内部数据 TpSlideProgressBar.cpp:6-24
。
struct TpSlideProgressBarData
{int32_t minValue = 0;int32_t maxValue = 0;double curValue = 0;TpShared<TpSurface> iconSurface;ItpPoint pressPoint;bool mouseLeftPress = false;TpSlideProgressBarData() : iconSurface(TpMakeShared<TpSurface>()){}~TpSlideProgressBarData(){}
};
核心数据成员包括:
minValue/maxValue
:进度条的值范围控制curValue
:当前进度值iconSurface
:图标显示资源pressPoint/mouseLeftPress
:鼠标交互状态追踪
功能实现详解
进度值管理
组件提供了完整的进度值管理接口,支持自定义范围的进度控制TpSlideProgressBar.cpp:53-64
。
void TpSlideProgressBar::setRange(const int32_t &minValue, const int32_t &maxValue)
{TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);progressData->minValue = minValue;progressData->maxValue = maxValue;if (progressData->maxValue <= progressData->minValue){progressData->maxValue = progressData->minValue + 1;}
}
进度设置时会自动进行边界检查,确保数值在有效范围内,并触发界面更新和信号发射TpSlideProgressBar.cpp:66-82
。
void TpSlideProgressBar::setValue(const int32_t &value)
{TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);progressData->curValue = value;if (progressData->curValue < progressData->minValue)progressData->curValue = progressData->minValue;else if (progressData->curValue > progressData->maxValue)progressData->curValue = progressData->maxValue;else{}onValueChanged.emit(progressData->curValue);update();
}
交互式拖拽机制
组件实现了完整的鼠标交互处理链:
鼠标按下事件记录交互状态 TpSlideProgressBar.cpp:104-117
bool TpSlideProgressBar::onMousePressEvent(TpMouseEvent *event)
{TpChildWidget::onMousePressEvent(event);TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);if (event->button() == BUTTON_LEFT){progressData->mouseLeftPress = event->state();progressData->pressPoint = event->globalPos();}return true;
}
拖拽过程中实时计算进度值 TpSlideProgressBar.cpp:133-163
bool TpSlideProgressBar::onMouseMoveEvent(TpMouseEvent *event)
{TpChildWidget::onMouseMoveEvent(event);TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);if (progressData->mouseLeftPress){ITpPoint curPos = event->globalPos();int32_t offsetX = curPos.x - progressData->pressPoint.x;progressData->pressPoint = curPos;// value偏移对应像素 (1.0 / (100 - 0))// double curValue = value() + (1.0 * offsetX) / ((width() - 4) / (progressData->maxValue - progressData->minValue));// setValue(curValue);progressData->curValue += (1.0 * offsetX) / ((width() - 4) / (progressData->maxValue - progressData->minValue));if (progressData->curValue < progressData->minValue)progressData->curValue = progressData->minValue;else if (progressData->curValue > progressData->maxValue)progressData->curValue = progressData->maxValue;else{}onValueChanged.emit(progressData->curValue);update();// std::cout << "progressData->curValue " << progressData->curValue << std::endl;}return true;
}
鼠标释放事件清理交互状态 TpSlideProgressBar.cpp:119-131
bool TpSlideProgressBar::onMouseRleaseEvent(TpMouseEvent *event)
{TpChildWidget::onMouseRleaseEvent(event);TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);if (event->button() == BUTTON_LEFT){progressData->mouseLeftPress = event->state();}return true;
}
信号槽通信
组件通过onValueChanged信号提供值变化事件通知 TpSlideProgressBar.h:37 ,实现与外部系统的解耦通信。
declare_signal(onValueChanged, int32_t);
绘制渲染逻辑
onPaintEvent方法实现了完整的进度条图形绘制逻辑TpSlideProgressBar.cpp:183-229
。
绘制过程包括:
进度填充:根据当前进度值计算填充宽度并绘制圆角填充区域 TpSlideProgressBar.cpp:193-209
// 绘制填充
double valuePercent = 1.0 * (progressData->curValue - progressData->minValue) / (progressData->maxValue - progressData->minValue);uint32_t valueWidth = valuePercent * (width() - 4);
if (valueWidth > width())valueWidth = width();if (valueWidth > 0)
{// uint32_t minRad = (valueWidth > (height() - 4) ? (height() - 4) : valueWidth) * roundCorners();double minRad = 1.0 * roundCorners() / height();minRad *= (height() - 4 - 2);// paintCanvas->roundedBox(2, 2, valueWidth - 4, height() - 4, minRad, curCssData->color());paintCanvas->roundedBox(2, 2, 2 + valueWidth, height() - 4, minRad, curCssData->color());
}
图标渲染:支持自定义图标的缩放显示 TpSlideProgressBar.cpp:211-226
// 绘制图标
if (progressData->iconSurface->hasSurface())
{TpShared<TpSurface> drawSurface = progressData->iconSurface->scaled(curCssData->iconSize(), curCssData->iconSize());if (!drawSurface)return true;int32_t imageWidth = drawSurface->width();int32_t imageHeight = drawSurface->height();TpCanvas *canvas = event->canvas();int32_t cy = (rect().h - imageHeight) / 2;paintCanvas->paintSurface(cy, cy, drawSurface);
}
样式系统集成
TpSlideProgressBar完全集成了PiXSingleGUI的CSS样式系统。在系统主题配置中,可以看到针对TpSlideProgressBar的样式定义purple-light.css:81-88
。
TpSlideProgressBar {height: 64dp;width: 305dp;icon-size: 33dp;background: rgba(0, 0, 0, 0.3);color: rgba(255, 255, 255, 1);border-radius: 16;
}
样式系统支持:
height/width
:组件尺寸配置icon-size
:图标尺寸设置background/color
:背景和填充颜色配置border-radius
:圆角边框设置
系统集成与应用场景
TpSlideProgressBar作为通用交互式进度控制组件,可广泛应用于:
- 音频/视频播放器的进度控制
- 系统设置中的参数调节滑块
- 多媒体应用的时间轴操作
- 任何需要用户交互式调节数值的场景
演示程序
#include "TpApp.h"
#include "TpFixScreen.h"
#include "TpLabel.h"
#include "TpSlideProgressBar.h"
#include "TpFont.h"int32_t main(int32_t argc, char *argv[])
{TpApp app(argc, argv);TpFixScreen *vScreen = new TpFixScreen();vScreen->setBackGroundColor(_RGBA(128, 128, 128, 255));vScreen->setVisible(true); // vScreen setvisible will be update displayapp.bindVScreen(vScreen);TpLabel *valueText = new TpLabel(vScreen);valueText->setText(TpString::number(100));valueText->setAlign(tinyPiX::AlignCenter);valueText->font()->setFontColor(_RGB(255, 255, 255),_RGB(255, 255, 255));valueText->font()->setFontSize(128);valueText->setWidth(600);valueText->setHeight(400);valueText->move(100, 100);TpSlideProgressBar *slider = new TpSlideProgressBar(vScreen);slider->setRange(0, 100);slider->setValue(100);slider->move(100, 60);slider->setIcon("/opt/tinyPiXCore/examples/SingleGUI/TpSlideProgressBar/liangdu.svg");TpSlideProgressBar *vSlider = new TpSlideProgressBar(vScreen);vSlider->setRange(0, 100); vSlider->setValue(0);vSlider->move(100, 400);vSlider->setIcon("/opt/tinyPiXCore/examples/SingleGUI/TpSlideProgressBar/yinliang.svg");connect(slider, onValueChanged, [=](int32_t value){ valueText->setText(TpString::number(value));vSlider->setValue(100-value); });connect(vSlider, onValueChanged, [=](int32_t value){ valueText->setText(TpString::number(value));slider->setValue(100-value); });vScreen->update();return app.run();
}
TinyPiXOS开发者联盟
源码级支持 + 真实项目:TinyPiXOS开发者联盟招募中,国产自主轻量级嵌入式设备桌面操作系统交流社群。
获取开发资料
官网网站
B 站视频
感谢支持和关注,如果对项目感兴趣,请点赞、收藏和转发!