Skip to content

Latest commit

 

History

History
281 lines (203 loc) · 6.41 KB

File metadata and controls

281 lines (203 loc) · 6.41 KB

🔘 Button Component - 按钮组件

状态:✅ 已完成
难度:⭐⭐
代码行数:~208 行


📋 组件概述

Button 是一个交互式按钮组件,演示了完整的鼠标交互、状态管理和视觉反馈系统。

核心功能

  • 三种交互状态:普通(NORMAL)、悬停(HOVER)、按下(PRESSED)
  • 平滑颜色过渡:使用插值动画实现状态切换
  • 点击事件处理:检测鼠标释放时的点击动作
  • 实时反馈:点击计数和窗口标题更新
  • 视觉指示器:状态圆点和计数条

🎨 视觉效果

按钮状态

状态 颜色 触发条件
NORMAL 蓝灰色 (0.3, 0.4, 0.6) 鼠标未悬停
HOVER 亮蓝色 (0.4, 0.5, 0.7) 鼠标悬停在按钮上
PRESSED 深蓝色 (0.2, 0.3, 0.5) 鼠标左键按下

组件布局

┌─────────────────────────────┐
│  ⚫🟡🔴 状态指示器             │
│  📊📊📊 点击计数条             │
│                             │
│      ┌─────────────┐        │
│      │   Button    │  ← 主按钮      │
│      │   [Text]    │        │
│      └─────────────┘        │
│                             │
└─────────────────────────────┘

🖱️ 交互演示

基本交互

  1. 移动鼠标到按钮上

    • 按钮颜色变亮(HOVER 状态)
    • 左上角状态指示器变黄色 🟡
  2. 点击按钮

    • 按钮颜色变深(PRESSED 状态)
    • 状态指示器变红色 🔴
    • 释放鼠标时触发 onClick() 事件
  3. 点击成功

    • 窗口标题更新为 "Button Component - Clicked N times"
    • 左上角绿色计数条增加一格
  4. 移开鼠标

    • 按钮恢复普通颜色
    • 状态指示器变灰色 ⚫

键盘控制

  • ESC - 退出程序

🎓 技术要点

1. 状态机管理

enum ButtonState {
    NORMAL,   // 普通状态
    HOVER,    // 悬停状态
    PRESSED   // 按下状态
};

状态转换逻辑

  • 鼠标在按钮外 → NORMAL
  • 鼠标在按钮内 + 未按下 → HOVER
  • 鼠标在按钮内 + 按下左键 → PRESSED

2. 鼠标碰撞检测

bool isMouseInside = (mouseX >= buttonX && 
                      mouseX <= buttonX + buttonWidth &&
                      mouseY >= buttonY && 
                      mouseY <= buttonY + buttonHeight);

使用 AABB(轴对齐包围盒)检测鼠标是否在按钮范围内。

3. 颜色插值动画

// 颜色平滑过渡
for (int i = 0; i < 4; i++) {
    float diff = targetColor[i] - currentColor[i];
    currentColor[i] += diff * colorTransitionSpeed * deltaTime;
}
  • 使用线性插值实现平滑的颜色过渡
  • colorTransitionSpeed = 8.0f 控制过渡速度

4. 点击事件检测

// 检测鼠标释放(点击完成)
if (currentState == PRESSED && !input->isMouseButtonPressed(0)) {
    onClick();  // 触发点击回调
}

只在鼠标释放时触发点击,防止误触发。

5. 窗口标题动态更新

void onClick() {
    clickCount++;
    char title[128];
    snprintf(title, sizeof(title), "Button Component - Clicked %d times", clickCount);
    window->setTitle(title);
}

📂 文件结构

button/
├── README.md                  # 本文档
├── button.cpp                 # 组件实现(208 行)
├── CMakeLists.txt             # 构建配置
├── assets/                    # 资源文件
│   └── shaders/              # 着色器
│       ├── triangle.vert     # 顶点着色器
│       ├── triangle.frag     # 片段着色器
│       ├── compile_shaders.bat
│       └── spv/              # 编译产物
│           ├── triangle_vert.spv
│           └── triangle_frag.spv
└── build/                     # 构建目录(自动生成)
    └── Release/
        └── button.dll        # 组件动态库

🚀 构建与运行

1. 编译着色器

cd examples/cpp/button/assets/shaders
compile_shaders.bat

2. 构建组件

cd examples/cpp/button
mkdir build
cd build
cmake ..
cmake --build . --config Release

3. 复制 DLL

copy Release\button.dll ..\..\..\native\build\Release\

4. 运行组件

cd ..\..\..\native
.\build\Release\bitui_native.exe .\build\Release\button.dll

💡 学习要点

初学者

  1. 鼠标输入处理

    • 如何获取鼠标位置
    • 如何检测鼠标按钮状态
    • 如何判断鼠标是否在区域内
  2. 状态管理

    • 使用枚举定义状态
    • 实现状态转换逻辑
    • 根据状态改变视觉表现
  3. 事件回调

    • 检测点击事件
    • 触发回调函数
    • 更新 UI 反馈

进阶开发者

  1. 动画系统

    • 线性插值(Lerp)实现
    • 时间增量(deltaTime)使用
    • 平滑过渡效果
  2. UI 反馈设计

    • 视觉状态指示
    • 即时反馈机制
    • 用户体验优化
  3. 颜色 Alpha 通道

    • RGBA 颜色数组的正确使用
    • 避免内存越界错误
    • API 接口规范遵守

🐛 常见问题

Q1: 按钮颜色不变?

A: 检查 colorTransitionSpeed 值,确保 deltaTime 正确传递。

Q2: 点击无反应?

A: 确保在鼠标释放时检测点击,而不是按下时。

Q3: 鼠标位置偏移?

A: 确认坐标系统,组件使用视图变换后的坐标(原点在屏幕中心)。

Q4: 编译错误 - 颜色数组?

A: 所有颜色数组必须是 float[4](RGBA),而不是 float[3]


📊 性能数据

从实际运行测试:

  • 平均帧率:~240 FPS
  • 帧时间:~4.2ms
  • 内存占用:< 1MB
  • CPU 使用:< 2%

🔗 相关组件

  • Switch - 开关组件(双状态切换)
  • ProgressBar - 进度条组件(状态机示例)
  • Slider - 滑动条组件(规划中)

📝 更新日志

  • 2025-10-12:✅ 组件完成,修复颜色数组维度问题
  • 2025-10-12:✅ 添加着色器编译
  • 2025-10-12:✅ 创建组件文档

作者:Bit Project 团队
最后更新:2025-10-12
版本:v1.0.0