最近尝试用 eel 写 reaper 脚本,模拟一个button组件,基本可以实现:
- 按钮边框,可控的 颜色 和 框线大小 (bd_size) ,
通过 gfx_rect() 绘制两层大小不一的矩形实现 - 文字自动居中,按钮自动调整大小,可控的内边距、文字颜色,
通过 gfx_measurestr() 获取字符串宽度,计算调整文本位置,和按钮矩形宽高。 - 鼠标位置判断,是否处于 button 范围内,以及鼠标是否按下,
通过全局变量 mouse_cap 获取鼠标位 置,在主循环记录一次到 mouse_state 变量,
在 button 函数判断鼠标位置、鼠标按下的键位。 - button 本身的鼠标状态需要记录和判断,暂时还没有实现,所以鼠标一直按住,
会一直重复运行判断内的代码,比如会反复执行 onclick 事件(假设有)。
不过 eel 的语言特性,感觉写一个UI框架是比较复杂的,加上 gfx 这种绘制方式比较底层,
之后估计会用其他UI方案,纯当经验分享了,下面是截图和代码。
// 同时设置绘制起始点、颜色
function set_pos_and_color(x,y,r,g,b)
(
gfx_x = x; gfx_y = y;
gfx_r = r; gfx_g = g; gfx_b = b;
);
// 封装矩形绘制方法,模仿按钮
function draw_rect(x,y,text,w,h,bd_r,bd_g,bd_b,bd_size,bg_r,bg_g,bg_b,lbl_x,lbl_y,lbl_r,lbl_g,lbl_b,)
(
// 绘制底层 border
set_pos_and_color(x,y,bd_r,bd_g,bd_b);
gfx_rect(x,y,w,h);
// 绘制内层
set_pos_and_color(x+bd_size,y+bd_size,bg_r,bg_g,bg_b);
gfx_rect(x+bd_size,y+bd_size,w-bd_size*2,h-bd_size*2);
// 绘制文本
set_pos_and_color(lbl_x,lbl_y,lbl_r,lbl_g,lbl_b);
gfx_drawstr(text);
);
// 按钮
function button(x,y,text)
(
this.x = x;
this.y = y;
this.text = text;
this.w = 0;
this.h = 0;
// 判断字符长度,自适应修改 w, h
gfx_measurestr(text,this.text_w,this.text_h);
this.text_w > this.w ? this.w = this.text_w + 40;
this.text_h > this.h ? this.h = this.text_h + 20;
// 计算文本位置,放到矩形中心
this.text_x = (this.x + this.w * 0.5) - (this.text_w * 0.5);
this.text_y = (this.y + this.h * 0.5)-(gfx_texth * 0.5);
this.x1 = this.x + this.w;
this.y1 = this.y + this.h;
this.bd_r = 0;
this.bd_g = 0.5;
this.bd_b = 0.5;
this.bd_size = 3;
this.bg_r = 0.9;
this.bg_g = 0.9;
this.bg_b = 0.9;
this.text_r = 0;
this.text_g = 0;
this.text_b = 0;
this.mouse_state = 0;
draw_rect(
this.x,
this.y,
this.text,
this.w,
this.h,
this.bd_r,
this.bd_g,
this.bd_b,
this.bd_size,
this.bg_r,
this.bg_g,
this.bg_b,
this.text_x,
this.text_y,
this.text_r,
this.text_g,
this.text_b
);
// 鼠标事件判断
(mouse_x > this.x && mouse_x < this.x1 && mouse_y > this.y && mouse_y < this.y1) ? (
// 改变内层颜色
this.bg_r = 0.8;
this.bg_g = 0.7;
this.bg_b = 0.9;
draw_rect(
this.x,
this.y,
this.text,
this.w,
this.h,
this.bd_r,
this.bd_g,
this.bd_b,
this.bd_size,
this.bg_r,
this.bg_g,
this.bg_b,
this.text_x,
this.text_y,
this.text_r,
this.text_g,
this.text_b
);
// 判断是否点击
mouse_cap == 1 && mouse_cap != this.mouse_state ? (
this.mouse_state = mouse_cap;
this.bg_r = 0.5;
this.bg_g = 0.5;
this.bg_b = 0.9;
draw_rect(
this.x,
this.y,
this.text,
this.w,
this.h,
this.bd_r,
this.bd_g,
this.bd_b,
this.bd_size,
this.bg_r,
this.bg_g,
this.bg_b,
this.text_x,
this.text_y,
this.text_r,
this.text_g,
this.text_b
);
);
);
);
function draw_status()
(
this.x = 10;
this.y = gfx_h - gfx_texth -10;
set_pos_and_color(this.x, this.y, 1, 1, 1);
gfx_printf("pos: (%d, %d), mouse_cap: %d", mouse_x, mouse_y, mouse_cap);
);
// 绘制函数
function draw()
(
button(100,100,"A");
button(100,150,"AA");
button(100,200,"AAA");
button(100,250,"abcdefghijk");
button(100,300,"哈");
button(100,350,"哈哈");
button(100,400,"哈哈哈");
draw_status();
);
// 主函数loop
function main()
(
set_pos_and_color(0,0,1,1,1);
mouse_cap == 0 ? mouse_state = 0 : mouse_state = 1;
// 绘制图形
draw();
// 更新画面,循环绘制
gfx_update();
gfx_getchar() >= 0 ? defer("main();");
);
// 初始化窗口
function init()
(
font_name = "Arial";
font_size = 20;
gfx_setfont(1, font_name, font_size);
gfx_init("EEL Test",400,600,0,300,300);
);
init();
main();