diff --git a/ViperFLProject/App/main2.vp b/ViperFLProject/App/main2.vp index 5caeede..9435dc8 100644 --- a/ViperFLProject/App/main2.vp +++ b/ViperFLProject/App/main2.vp @@ -1,20 +1,119 @@ -# main2.vp — ViperFLProject fltk GUI 测试 +# main2.vp — ViperFLProject fltk GUI 测试(回调 + 控件展示) # # 构建需 TPV/TPC 支持 project.vpj linker.static_libs 静态链接 # (本工程已配置链接 ../includes/fltk/cfltk/build 下的 cfltk2 + FLTK 静态库)。 -import t +# +# 回调说明:Viper 模块级函数可直接作为 Fl_Callback 传入(TPV 自动把函数名 +# 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 + + +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: t.CDouble = 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_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(400, 300, "FLTK from Viper") - box = fltk.Fl_Box(100, 60, 200, 40, "Hello, FLTK!") - btn = fltk.Fl_Button(150, 200, 100, 30, "OK") + 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, 300, 30, "Type here") + go = fltk.Fl_Button(320, 110, 60, 30, "Go") + spinner = fltk.Fl_Spinner(400, 110, 120, 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() - win.show() - # 阻塞直到所有窗口关闭 + # 保存全局指针(回调用) + 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) + + # 数值微调框 + 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