-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathslider.cpp
More file actions
299 lines (249 loc) · 10.3 KB
/
slider.cpp
File metadata and controls
299 lines (249 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
/**
* Slider Component
*
* 滑动条组件示例
* 演示鼠标拖动、数值映射和范围控制
*/
#include "runtime_api.h"
#include <cmath>
#include <cstdio>
class SliderComponent : public BitHCI::IComponent {
private:
// 运行时接口
BitHCI::IRenderer* renderer = nullptr;
BitHCI::IInput* input = nullptr;
BitHCI::IWindow* window = nullptr;
// 滑动条状态
bool wasMousePressed = false;
int draggedSlider = -1; // 当前拖动的滑块索引(-1 表示无)
// 滑动条配置
struct SliderData {
float x, y, width, height; // 滑轨位置和大小
float* value; // 值指针(0.0 - 1.0)
float min, max; // 值范围
const char* label; // 标签
const char* unit; // 单位
};
// 多个滑动条示例
float volumeValue = 0.7f; // 音量:70%
float brightnessValue = 0.5f; // 亮度:50%
float speedValue = 0.3f; // 速度:30%
float opacityValue = 1.0f; // 不透明度:100%
SliderData sliders[4];
// 颜色配置
float colorTrack[4] = {0.25f, 0.25f, 0.3f, 1.0f}; // 滑轨
float colorTrackFill[4] = {0.3f, 0.7f, 0.9f, 1.0f}; // 滑轨填充
float colorThumb[4] = {0.4f, 0.8f, 1.0f, 1.0f}; // 滑块
float colorThumbHover[4] = {0.5f, 0.9f, 1.0f, 1.0f}; // 滑块悬停
float colorThumbDrag[4] = {0.2f, 0.6f, 0.8f, 1.0f}; // 滑块拖动
float colorText[4] = {0.9f, 0.9f, 0.9f, 1.0f}; // 文本
float colorValue[4] = {0.6f, 0.8f, 1.0f, 1.0f}; // 数值
public:
/**
* 组件初始化
*/
void onInit(BitHCI::IWindow* window,
BitHCI::IRenderer* renderer,
BitHCI::IInput* input,
BitHCI::IResourceManager* resources) override {
this->window = window;
this->renderer = renderer;
this->input = input;
// 设置清屏颜色
renderer->setClearColor(0.1f, 0.1f, 0.12f, 1.0f);
// 初始化滑动条数据
sliders[0] = {-150.0f, -80.0f, 250.0f, 8.0f, &volumeValue, 0.0f, 100.0f, "Volume", "%"};
sliders[1] = {-150.0f, -20.0f, 250.0f, 8.0f, &brightnessValue, 0.0f, 100.0f, "Brightness", "%"};
sliders[2] = {-150.0f, 40.0f, 250.0f, 8.0f, &speedValue, 0.0f, 10.0f, "Speed", "x"};
sliders[3] = {-150.0f, 100.0f, 250.0f, 8.0f, &opacityValue, 0.0f, 1.0f, "Opacity", ""};
}
/**
* 组件更新
*/
void onUpdate(float deltaTime) override {
// ESC 键退出
if (input->isKeyJustPressed(27)) {
window->close();
}
// R 键重置所有值
if (input->isKeyJustPressed('R')) {
volumeValue = 0.7f;
brightnessValue = 0.5f;
speedValue = 0.3f;
opacityValue = 1.0f;
}
// 鼠标交互
bool isMousePressed = input->isMouseButtonPressed(0);
float mouseX, mouseY;
input->getMousePosition(mouseX, mouseY);
if (isMousePressed) {
if (!wasMousePressed) {
// 鼠标按下瞬间:检查是否点击滑块
for (int i = 0; i < 4; i++) {
if (isPointOnSlider(mouseX, mouseY, sliders[i])) {
draggedSlider = i;
updateSliderValue(mouseX, sliders[i]);
break;
}
}
} else if (draggedSlider >= 0) {
// 拖动中:更新滑块值
updateSliderValue(mouseX, sliders[draggedSlider]);
}
} else {
// 鼠标释放:停止拖动
draggedSlider = -1;
}
wasMousePressed = isMousePressed;
}
/**
* 组件渲染
*/
void onRender() override {
// 获取鼠标位置(用于悬停效果)
float mouseX, mouseY;
input->getMousePosition(mouseX, mouseY);
// 绘制标题
renderer->drawText("Slider Component Demo", -180, -140, colorText, 20.0f);
renderer->drawText("[R] Reset [ESC] Quit", -180, -120, colorText, 12.0f);
// 绘制所有滑动条
for (int i = 0; i < 4; i++) {
bool isHovered = isPointOnSlider(mouseX, mouseY, sliders[i]);
bool isDragging = (draggedSlider == i);
drawSlider(sliders[i], isHovered, isDragging);
}
// 绘制预览区域
drawPreview();
}
/**
* 组件销毁
*/
void onDestroy() override {
// 清理资源
}
private:
/**
* 检查点是否在滑动条上(包括滑块)
*/
bool isPointOnSlider(float x, float y, const SliderData& slider) const {
// 滑块位置
float thumbX = slider.x + slider.width * (*(slider.value));
float thumbRadius = 12.0f;
// 检查是否在滑块上(圆形碰撞)
float dx = x - thumbX;
float dy = y - (slider.y + slider.height / 2);
if (dx * dx + dy * dy <= thumbRadius * thumbRadius) {
return true;
}
// 检查是否在滑轨上(矩形碰撞)
return x >= slider.x && x <= slider.x + slider.width &&
y >= slider.y - 10 && y <= slider.y + slider.height + 10;
}
/**
* 更新滑动条的值
*/
void updateSliderValue(float mouseX, const SliderData& slider) {
// 计算新值(0.0 - 1.0)
float newValue = (mouseX - slider.x) / slider.width;
// 限制范围
if (newValue < 0.0f) newValue = 0.0f;
if (newValue > 1.0f) newValue = 1.0f;
// 更新值
*(slider.value) = newValue;
}
/**
* 绘制单个滑动条
*/
void drawSlider(const SliderData& slider, bool isHovered, bool isDragging) {
float trackY = slider.y + slider.height / 2;
// 1. 绘制标签
renderer->drawText(slider.label, slider.x, slider.y - 25, colorText, 14.0f);
// 2. 绘制滑轨(未填充部分)
renderer->drawRectangle(slider.x, slider.y, slider.width, slider.height, colorTrack);
// 3. 绘制滑轨填充部分
float fillWidth = slider.width * (*(slider.value));
if (fillWidth > 0) {
renderer->drawRectangle(slider.x, slider.y, fillWidth, slider.height, colorTrackFill);
}
// 4. 绘制滑块
float thumbX = slider.x + slider.width * (*(slider.value));
float thumbY = trackY;
float thumbRadius = 12.0f;
// 滑块颜色(根据状态)
float* thumbColor = colorThumb;
if (isDragging) {
thumbColor = colorThumbDrag;
} else if (isHovered) {
thumbColor = colorThumbHover;
}
// 绘制滑块阴影
float shadowColor[4] = {0.0f, 0.0f, 0.0f, 0.3f};
renderer->drawCircle(thumbX + 2, thumbY + 2, thumbRadius, shadowColor);
// 绘制滑块
renderer->drawCircle(thumbX, thumbY, thumbRadius, thumbColor);
// 绘制滑块边框
float borderColor[4] = {0.9f, 0.9f, 0.9f, 0.5f};
renderer->drawCircle(thumbX, thumbY, thumbRadius, borderColor);
renderer->drawCircle(thumbX, thumbY, thumbRadius - 2.0f, thumbColor);
// 5. 绘制数值
char valueText[64];
float actualValue = slider.min + (slider.max - slider.min) * (*(slider.value));
// 根据范围格式化数值
if (slider.max <= 1.0f) {
sprintf_s(valueText, sizeof(valueText), "%.2f%s", actualValue, slider.unit);
} else if (slider.max <= 10.0f) {
sprintf_s(valueText, sizeof(valueText), "%.1f%s", actualValue, slider.unit);
} else {
sprintf_s(valueText, sizeof(valueText), "%.0f%s", actualValue, slider.unit);
}
float valueX = slider.x + slider.width + 15;
float valueY = slider.y;
renderer->drawText(valueText, valueX, valueY, colorValue, 14.0f);
}
/**
* 绘制预览区域
*/
void drawPreview() {
// 背景框
float previewX = 20.0f;
float previewY = -140.0f;
float previewW = 160.0f;
float previewH = 260.0f;
float bgColor[4] = {0.2f, 0.2f, 0.25f, 1.0f};
renderer->drawRectangle(previewX, previewY, previewW, previewH, bgColor);
// 标题
renderer->drawText("Live Preview:", previewX + 10, previewY + 10, colorText, 14.0f);
// 根据滑动条的值绘制预览
float centerX = previewX + previewW / 2;
float centerY = previewY + previewH / 2;
// 大小受 speed 影响
float baseRadius = 30.0f;
float radius = baseRadius * (1.0f + speedValue * 2.0f);
// 颜色受 volume 和 brightness 影响
float r = 0.3f + volumeValue * 0.6f;
float g = 0.5f + brightnessValue * 0.4f;
float b = 0.9f;
float a = opacityValue;
float previewColor[4] = {r, g, b, a};
// 绘制预览圆
renderer->drawCircle(centerX, centerY, radius, previewColor);
// 绘制说明文本
renderer->drawText("Volume -> Red", previewX + 10, previewY + previewH - 80, colorText, 10.0f);
renderer->drawText("Brightness -> Green", previewX + 10, previewY + previewH - 65, colorText, 10.0f);
renderer->drawText("Speed -> Size", previewX + 10, previewY + previewH - 50, colorText, 10.0f);
renderer->drawText("Opacity -> Alpha", previewX + 10, previewY + previewH - 35, colorText, 10.0f);
// 绘制边框
float borderColor[4] = {0.4f, 0.4f, 0.45f, 1.0f};
float borderW = 2.0f;
// 上
renderer->drawRectangle(previewX, previewY, previewW, borderW, borderColor);
// 下
renderer->drawRectangle(previewX, previewY + previewH - borderW, previewW, borderW, borderColor);
// 左
renderer->drawRectangle(previewX, previewY, borderW, previewH, borderColor);
// 右
renderer->drawRectangle(previewX + previewW - borderW, previewY, borderW, previewH, borderColor);
}
};
// 导出组件
BITHCI_COMPONENT(SliderComponent)