-
Notifications
You must be signed in to change notification settings - Fork 0
/
sx_lib.h
411 lines (347 loc) · 13 KB
/
sx_lib.h
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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
/**
******************************************************************************
* @file : component_structs.h
* @author : BUPT_ShenXu
* @date : 2023/4/27
* @detail : 自制组件库
******************************************************************************
*/
#ifndef VISUAL_VERSION_SX_LIB_H
#define VISUAL_VERSION_SX_LIB_H
#include <iostream>
#include <unistd.h>
#include "string"
#include "easyx.h"
#include <conio.h>
#include <cstdlib>
#include "sys/time.h"
using namespace std;
///窗口结构体
struct SX_window;
///样式结构体
struct Style;
///所有组件的父类
struct ComponentVisual;
/// 非手动调用,将组件添加到组件流当中
/// \param component
void addComponent(ComponentVisual *component);
void fpsUserRender();
long long getCurrentTime();
/// 根据id获取组件指针
/// \param id 所需要的组件的id
/// \return 查找组件的指针
ComponentVisual *getComponentById(const string &id);
/// 从组件流中删除指定组件
/// \param component 指定组件的指针
void del_component(ComponentVisual *component);
///清空组件流
void clearAll();
///子组件
struct SX_button;
struct SX_text;
struct SX_inputBox;
struct SX_image;
///组件流单位
typedef struct ComponentsVisual {
ComponentsVisual *after;
ComponentsVisual *before;
ComponentVisual *that;
} Components;
void *renderAll(void *);
///创建窗口
typedef struct SX_window {
SX_window(int width, int height, COLORREF background_color = WHITE) {
initgraph(width, height);
setbkcolor(background_color);
cleardevice();
setbkmode(TRANSPARENT);
}
} SX_window;
typedef struct Component {
} Component;
typedef struct ComponentNonVisual : Component {
} ComponentNonVisual;
///可视组件样式
struct Style {
//组件位置
int top, left;
//组件大小
int width, height;
//背景颜色
COLORREF background_color;
//边框样式
int border_width, border_style;
COLORREF border_color;
//字体(样式&内容)
int font_size;
LPCTSTR font_style;
COLORREF font_color;
};
///可视组件
struct ComponentVisual : Component {
//是否已经被渲染
bool is_render;
//是否被点击
bool clicked;
//构造方法
ComponentVisual() {
show = true;
leftClickDown = rightClickDown = midClickDown = leftClickUp = rightClickUp = midClickUp = leftDoubleClick =
rightDoubleClick = midDoubleClick = leftClick = rightClick = rightAndLeftDown = nullptr;
mouseWheel = nullptr;
keyDown = nullptr;
blur = nullptr;
is_render = false;
content = id = "";
clicked = false;
}
//是否显示
bool show;
//组件样式
struct Style style;
//内容
string content;
//组件ID
string id;
///渲染事件
virtual void render_this() {}
void (*mouseWheel)(int pointX, int pointY, int wheelSize, ComponentVisual *component);
/// 左键按下触发事件
/// \param pointX 点击x坐标
/// \param pointY 点击y坐标
/// \param component 触发事件的组件指针
void (*leftClickDown)(int pointX, int pointY, ComponentVisual *component);
void (*leftClickUp)(int pointX, int pointY, ComponentVisual *component);
void (*leftDoubleClick)(int pointX, int pointY, ComponentVisual *component);
void (*leftClick)(int pointX, int pointY, ComponentVisual *component);
/// 右键触发事件
/// \param pointX 点击x坐标
/// \param pointY 点击y坐标
/// \param component 触发事件的组件指针
void (*rightClickDown)(int pointX, int pointY, ComponentVisual *component);
void (*rightClickUp)(int pointX, int pointY, ComponentVisual *component);
void (*rightDoubleClick)(int pointX, int pointY, ComponentVisual *component);
void (*rightClick)(int pointX, int pointY, ComponentVisual *component);
void (*rightAndLeftDown)(int pointX, int pointY, ComponentVisual *component);
/// 中键触发事件
/// \param pointX 点击x坐标
/// \param pointY 点击y坐标
/// \param component 触发事件的组件指针
void (*midClickDown)(int pointX, int pointY, ComponentVisual *component);
void (*midClickUp)(int pointX, int pointY, ComponentVisual *component);
void (*midDoubleClick)(int pointX, int pointY, ComponentVisual *component);
/// 组件失去焦点时
/// \param component 实现该事件的组件
void (*blur)(ComponentVisual *component);
/// 键盘按下触发事件
/// \param key 键盘按下的字符
/// \param component 实现该事件的组件
void (*keyDown)(char key, ComponentVisual *component);
/// 判断点击是否为当前组件
/// \param pointX 点击的x坐标
/// \param pointY 点击的y坐标
/// \return 是否点击的当前组件
virtual bool is_click_me(int pointX, int pointY) {
bool is_me = pointX > this->style.left
&& pointX < this->style.left + this->style.width
&& pointY > this->style.top
&& pointY < this->style.top + this->style.height
&& this->show
&& this->is_render;
if (!is_me && this->clicked) {
if (this->blur != nullptr) {
this->blur(this);
}
}
this->clicked = is_me;
return is_me;
}
};
typedef struct SX_button : ComponentVisual {
SX_button() : ComponentVisual() {
addComponent(this);
}
explicit SX_button(int left, int top, int width, int height) : SX_button() {
this->style.left = left;
this->style.top = top;
this->style.width = width;
this->style.height = height;
this->style.font_size = 10;
this->style.font_style = _T("Yahei");
this->style.border_width = 0;
this->style.background_color = WHITE;
this->style.font_color = BLACK;
this->style.border_style = BS_SOLID;
this->style.border_color = BLACK;
}
void render_this() override {
setlinestyle(this->style.border_style, this->style.border_width);
setlinecolor(this->style.border_color);
setlinestyle(this->style.border_style);
settextstyle(this->style.font_size, this->style.font_size / 1.8, this->style.font_style);
settextcolor(this->style.font_color);
setfillcolor(this->style.background_color);
setfillstyle(BS_SOLID);
auto *content = new TCHAR[this->content.size() + 1];
content[this->content.size()] = 0;
copy(this->content.begin(), this->content.end(), content);
fillrectangle(this->style.left, this->style.top, this->style.left + this->style.width,
this->style.top + this->style.height);
outtextxy(this->style.left + 2, this->style.top + (this->style.height - this->style.font_size) / 2, content);
}
} SX_button;
typedef struct SX_text : ComponentVisual {
SX_text() : ComponentVisual() {
addComponent(this);
}
explicit SX_text(string content, int left, int top) : SX_text() {
this->content = std::move(content);
this->style.left = left;
this->style.top = top;
this->style.font_size = 10;
this->style.font_style = _T("Yahei");
this->style.width = this->style.height = this->style.border_width = 0;
this->style.background_color = WHITE;
this->style.font_color = BLACK;
this->style.border_style = BS_SOLID;
this->style.border_color = BLACK;
}
void render_this() override {
settextstyle(this->style.font_size, this->style.font_size / (1.8), this->style.font_style);
settextcolor(this->style.font_color);
auto *content = new TCHAR[this->content.size() + 1];
content[this->content.size()] = 0;
copy(this->content.begin(), this->content.end(), content);
outtextxy(this->style.left, this->style.top, content);
}
bool is_click_me(int pointX, int pointY) override {
return false;
}
} SX_text;
typedef struct SX_inputBox : ComponentVisual {
int maxCharNum;
private:
COLORREF last_border_color;
static void inputBoxClicked(int pointX, int pointY, ComponentVisual *component) {
auto this_input_box = (SX_inputBox *) component;
if (this_input_box->style.border_color != BLACK) {
this_input_box->last_border_color = this_input_box->style.border_color;
}
this_input_box->style.border_color = BLACK;
}
static void inputBoxInput(char key, ComponentVisual *component) {
auto this_input_box = (SX_inputBox *) component;
if (this_input_box->clicked) {
if (key == '\b' && component->content.length() != 0)
this_input_box->content.erase(this_input_box->content.end() - 1);
if (this_input_box->maxCharNum != -1 &&
this_input_box->content.length() == this_input_box->maxCharNum)
return;
if (key != '\b') this_input_box->content += (char) key;
}
}
static void inputBoxBlur(ComponentVisual *component) {
auto this_input_box = (SX_inputBox *) component;
this_input_box->style.border_color = this_input_box->last_border_color;
}
public:
SX_inputBox() : ComponentVisual() {
this->maxCharNum = -1;
addComponent(this);
this->leftClick = inputBoxClicked;
this->keyDown = inputBoxInput;
this->blur = inputBoxBlur;
}
SX_inputBox(int left, int top, int width, int height) : SX_inputBox() {
this->style.left = left;
this->style.top = top;
this->style.width = width;
this->style.height = height;
this->style.font_size = height - 1;
this->style.border_width = 1;
this->style.border_color = RGB(200, 200, 200);
this->style.background_color = WHITE;
}
void render_this() override {
setlinestyle(this->style.border_style, this->style.border_width);
setlinecolor(this->style.border_color);
setlinestyle(this->style.border_style);
settextstyle(this->style.font_size, this->style.font_size / (1.8), this->style.font_style);
settextcolor(this->style.font_color);
setfillcolor(this->style.background_color);
setfillstyle(BS_SOLID);
fillrectangle(this->style.left, this->style.top, this->style.left + this->style.width,
this->style.top + this->style.height);
auto *context = new TCHAR[this->content.size() + 1];
context[this->content.size()] = 0;
copy(this->content.begin(), this->content.end(), context);
outtextxy(this->style.left + this->style.border_width,
this->style.top + (this->style.height - this->style.font_size) / 2, context);
}
} SX_inputBox;
typedef struct SX_image : ComponentVisual {
//图片路径
string src;
SX_image() : ComponentVisual() {
addComponent(this);
}
explicit SX_image(string src, int top, int left, int width, int height) : SX_image() {
this->src = std::move(src);
this->style.top = top;
this->style.left = left;
this->style.width = width;
this->style.height = height;
}
void render_this() override {
auto *src_t = new TCHAR[this->src.size() + 1];
src_t[this->src.size()] = 0;
copy(this->src.begin(), this->src.end(), src_t);
IMAGE img;
loadimage(&img, src_t, this->style.width - this->style.border_width * 2,
this->style.height - this->style.border_width * 2);
setfillcolor(this->style.border_color);
setfillstyle(BS_SOLID);
solidrectangle(this->style.left, this->style.top, this->style.left + this->style.width,
this->style.top + this->style.height);
putimage(this->style.left + this->style.border_width, this->style.top + this->style.border_width, &img);
}
} SX_image;
///计时器组件
typedef struct SX_timer : ComponentNonVisual {
private:
static void *timing_finish_inner(void *timer) {
auto clock = (SX_timer *) timer;
while (true) {
Sleep(clock->sleep_time);
if (!clock->started || clock->sleep_time == -1)break;
if (clock->ifFree)return nullptr;
if (clock->timing_finish != nullptr)clock->timing_finish(clock);
}
}
//是否要被销毁
bool ifFree;
//计时线程
pthread_t pthread;
public:
//每隔多长时间执行一次(单位:秒)
int sleep_time;
//是否倒计时
bool started;
//计时结束后执行的函数
void (*timing_finish)(SX_timer *);
SX_timer() {
ifFree = false;
timing_finish = nullptr;
started = false;
sleep_time = -1;
pthread_create(&pthread, nullptr, timing_finish_inner, (void *) this);
}
explicit SX_timer(int sleep_time) : SX_timer() {
this->sleep_time = sleep_time;
}
void free_timer() {
this->ifFree = true;
delete this;
}
} SX_timer;
#endif //VISUAL_VERSION_SX_LIB_H