159 lines
5.0 KiB
Plaintext
159 lines
5.0 KiB
Plaintext
# main2.vp — ViperFLProject fltk GUI 测试(回调 + 控件展示)
|
||
#
|
||
# 构建需 VPC/TPC 支持 project.vpj linker.static_libs 静态链接
|
||
# (本工程已配置链接 ../includes/fltk/cfltk/build 下的 cfltk2 + FLTK 静态库)。
|
||
#
|
||
# 回调说明:Viper 模块级函数可直接作为 Fl_Callback 传入(VPC 自动把函数名
|
||
# bitcast 为函数指针)。回调签名统一为 def cb(w: bytes, data: bytes),
|
||
# 其中 w 是触发回调的控件指针,data 是注册时传入的用户数据。
|
||
import t, c
|
||
import stdlib
|
||
import viperlib
|
||
import fltk
|
||
|
||
|
||
# 模块级全局:供回调访问 main() 中创建的控件指针(回调是 C 层直接调用,
|
||
# 拿不到 main 的局部变量);空指针用 None(C null),不能用整数 0。
|
||
term_ptr: t.CPtr = None
|
||
status_ptr: t.CPtr = None
|
||
scheme_idx: int = 0
|
||
theme_idx: int = 0
|
||
|
||
|
||
def on_btn_click(w: bytes, data: bytes):
|
||
"""按钮点击回调:改按钮文字 + 状态栏显示"""
|
||
fltk.Fl_Widget_set_label(w, "Clicked!")
|
||
fltk.Fl_Widget_redraw(w)
|
||
fltk.Fl_Output_set_value(status_ptr, "Button clicked")
|
||
|
||
|
||
def on_check(w: bytes, data: bytes):
|
||
"""复选框回调:状态栏显示勾选状态"""
|
||
v: int = fltk.Fl_Check_Button_is_checked(w)
|
||
if v != 0:
|
||
fltk.Fl_Output_set_value(status_ptr, "Checked")
|
||
else:
|
||
fltk.Fl_Output_set_value(status_ptr, "Unchecked")
|
||
|
||
|
||
def on_slider(w: bytes, data: bytes):
|
||
"""滑动条回调:状态栏实时显示数值"""
|
||
v: double = fltk.Fl_Slider_value(w)
|
||
buf: bytes = stdlib.malloc(32)
|
||
if buf is not None:
|
||
viperlib.snprintf(buf, 32, "Slider = %.2f", v)
|
||
fltk.Fl_Output_set_value(status_ptr, buf)
|
||
stdlib.free(buf)
|
||
|
||
|
||
def on_go(w: bytes, data: bytes):
|
||
"""按钮回调:读取输入框文本 → 终端打印"""
|
||
txt: str = fltk.Fl_Input_value(data)
|
||
fltk.Fl_Terminal_append(term_ptr, "input: ")
|
||
fltk.Fl_Terminal_append(term_ptr, txt)
|
||
fltk.Fl_Terminal_append(term_ptr, "\n")
|
||
|
||
|
||
def on_menu_open(w: bytes, data: bytes):
|
||
fltk.Fl_Output_set_value(status_ptr, "Menu: File/Open")
|
||
|
||
|
||
def on_menu_about(w: bytes, data: bytes):
|
||
fltk.Fl_Output_set_value(status_ptr, "Menu: Help/About")
|
||
|
||
|
||
def on_style(w: bytes, data: bytes):
|
||
"""风格切换回调:base→plastic→gtk+→gleam→oxy 循环"""
|
||
global scheme_idx
|
||
scheme_idx = scheme_idx + 1
|
||
if scheme_idx == 1:
|
||
fltk.Fl.set_scheme("plastic")
|
||
elif scheme_idx == 2:
|
||
fltk.Fl.set_scheme("gtk+")
|
||
elif scheme_idx == 3:
|
||
fltk.Fl.set_scheme("gleam")
|
||
elif scheme_idx == 4:
|
||
fltk.Fl.set_scheme("oxy")
|
||
else:
|
||
fltk.Fl.set_scheme("base")
|
||
scheme_idx = 0
|
||
fltk.Fl_Output_set_value(status_ptr, f"Scheme: {fltk.Fl.scheme_string()}")
|
||
|
||
|
||
def on_theme(w: bytes, data: bytes):
|
||
"""Fl_Theme 主题切换:base→Dark→Metro 循环"""
|
||
global theme_idx
|
||
theme_idx = theme_idx + 1
|
||
if theme_idx == 1:
|
||
fltk.Fl.set_theme_dark()
|
||
elif theme_idx == 2:
|
||
fltk.Fl.set_theme_metro()
|
||
else:
|
||
fltk.Fl.set_scheme("base")
|
||
fltk.Fl.reload_scheme()
|
||
theme_idx = 0
|
||
fltk.Fl_Output_set_value(status_ptr, f"Theme: {theme_idx}")
|
||
|
||
|
||
def on_tick(w: bytes, data: bytes):
|
||
"""定时器回调:每秒终端打印一次并续订"""
|
||
fltk.Fl_Terminal_append(term_ptr, "tick\n")
|
||
fltk.Fl.add_timeout(1.0, on_tick, 0)
|
||
|
||
|
||
def main() -> int:
|
||
global term_ptr, status_ptr
|
||
fltk.Fl_init_all()
|
||
|
||
win = fltk.Fl_Window(600, 460, "Viper FLTK Demo")
|
||
menubar = fltk.Fl_Menu_Bar(0, 0, 600, 25)
|
||
status = fltk.Fl_Output(10, 30, 580, 25)
|
||
btn = fltk.Fl_Button(10, 70, 120, 30, "Click Me")
|
||
check = fltk.Fl_Check_Button(150, 70, 100, 30, "Enable")
|
||
slider = fltk.Fl_Slider(280, 70, 200, 30)
|
||
input_ = fltk.Fl_Input(10, 110, 210, 30, "Type here")
|
||
go = fltk.Fl_Button(230, 110, 55, 30, "Go")
|
||
style = fltk.Fl_Button(295, 110, 55, 30, "Style")
|
||
theme = fltk.Fl_Button(360, 110, 55, 30, "Theme")
|
||
spinner = fltk.Fl_Spinner(425, 110, 100, 30)
|
||
browser = fltk.Fl_Browser(10, 150, 280, 140)
|
||
tree = fltk.Fl_Tree(300, 150, 280, 140)
|
||
term = fltk.Fl_Terminal(10, 300, 570, 120, "Terminal")
|
||
win.end()
|
||
|
||
# 保存全局指针(回调用)
|
||
term_ptr = t.CPtr(term._ptr)
|
||
status_ptr = t.CPtr(status._ptr)
|
||
|
||
# 菜单(回调 + 快捷键 Ctrl+O:0x4000 | 'o'(111))
|
||
menubar.add("File/Open", 0x4000 | 111, 0, on_menu_open)
|
||
menubar.add("Help/About", 0, 0, on_menu_about)
|
||
|
||
# 回调注册
|
||
btn.set_callback(on_btn_click, 0)
|
||
check.set_callback(on_check, 0)
|
||
slider.set_callback(on_slider, 0)
|
||
go.set_callback(on_go, input_._ptr)
|
||
style.set_callback(on_style, 0)
|
||
theme.set_callback(on_theme, 0)
|
||
|
||
# 数值微调框
|
||
spinner.set_minimum(0.0)
|
||
spinner.set_maximum(100.0)
|
||
spinner.set_step(1.0)
|
||
spinner.set_value(42.0)
|
||
|
||
# 列表 + 树
|
||
browser.add("Item 1")
|
||
browser.add("Item 2")
|
||
browser.add("Item 3")
|
||
tree.add("Root/Child A/Leaf 1")
|
||
tree.add("Root/Child B")
|
||
|
||
# 定时器
|
||
fltk.Fl.add_timeout(1.0, on_tick, 0)
|
||
|
||
win.show()
|
||
fltk.Fl.run()
|
||
return 0
|