- 生成 24 个 _cfl*.vp(10327 条 extern 声明)+ _types/_enums 常量 - __init__.vp 提供 Fl/Fl_Widget/Fl_Window/Fl_Button/Fl_Input/Fl_Text_Buffer/Fl_Group/Fl_Menu_Bar/Fl_Native_File_Chooser 等包装类 - 回调(Fl_Callback)按 bytes 不透明处理,菜单回调位传 t.CPtr(0) - 新增 examples/hello.vp、dialog.vp 冒烟样例,26 个 .vp 全部通过 vast parse - 内嵌 cfltk(C API 封装)与 FLTK 1.4 完整源码,构建目标 cfltk2
113 lines
3.7 KiB
C++
113 lines
3.7 KiB
C++
#ifndef __CFL_WIDGET_HPP__
|
|
#define __CFL_WIDGET_HPP__
|
|
|
|
#include <FL/Fl_Widget.H>
|
|
|
|
template <class T, class U>
|
|
struct is_same {
|
|
constexpr static inline bool value = false;
|
|
};
|
|
|
|
template <class T>
|
|
struct is_same<T, T> {
|
|
constexpr static inline bool value = true;
|
|
};
|
|
|
|
template <typename T>
|
|
struct Widget_Derived : public T {
|
|
Widget_Derived(const Widget_Derived &) = delete;
|
|
Widget_Derived(Widget_Derived &&) = delete;
|
|
Widget_Derived &operator=(const Widget_Derived &other) = delete;
|
|
Widget_Derived &operator=(Widget_Derived &&other) = delete;
|
|
void *ev_data_ = nullptr;
|
|
void *draw_data_ = nullptr;
|
|
void *resize_data_ = nullptr;
|
|
void *deleter_data_ = nullptr;
|
|
bool super_draw = true;
|
|
bool super_draw_first = true;
|
|
bool super_handle_first = true;
|
|
|
|
using handler = int (*)(Fl_Widget *, int, void *data);
|
|
handler inner_handler = nullptr;
|
|
using drawer = void (*)(Fl_Widget *, void *);
|
|
drawer inner_drawer = nullptr;
|
|
using resizer = void (*)(Fl_Widget *, int, int, int, int, void *);
|
|
resizer resize_handler = nullptr;
|
|
using deleter_fp = void (*)(Fl_Widget *, void *);
|
|
deleter_fp deleter = nullptr;
|
|
|
|
Widget_Derived(int x, int y, int w, int h, const char *title = nullptr)
|
|
: T(x, y, w, h, title) {
|
|
}
|
|
operator T *() {
|
|
return (T *)this;
|
|
}
|
|
|
|
static T *from_dyn_ptr(Fl_Widget *ptr) {
|
|
return dynamic_cast<T *>(ptr);
|
|
}
|
|
|
|
static Widget_Derived *from_derived_dyn_ptr(Fl_Widget *ptr) {
|
|
return dynamic_cast<Widget_Derived *>(ptr);
|
|
}
|
|
|
|
void widget_resize(int x, int y, int w, int h) {
|
|
Fl_Widget::resize(x, y, w, h);
|
|
this->redraw();
|
|
}
|
|
void resize(int x, int y, int w, int h) override {
|
|
T::resize(x, y, w, h);
|
|
if (this->as_window() == this->top_window()) {
|
|
LOCK(Fl::handle(28, this->top_window()));
|
|
}
|
|
if (resize_handler)
|
|
resize_handler(this, x, y, w, h, resize_data_);
|
|
}
|
|
|
|
// Widget event handler. Manages execution of both event handlers:
|
|
// inner_handler is the handler defined by end-user program, and may not
|
|
// exist T::handle is the built-in handler in the fltk widget
|
|
int handle(int event) override {
|
|
if (super_handle_first) {
|
|
int ret = T::handle(event);
|
|
// Both handlers always executed, T::handle executes first
|
|
if (inner_handler) {
|
|
int local = inner_handler(this, event, ev_data_);
|
|
return ret | local;
|
|
} else {
|
|
return ret;
|
|
}
|
|
} else {
|
|
// inner_handler executes first. T::handle only executes if
|
|
// inner_handler returns false
|
|
if (inner_handler) {
|
|
if (inner_handler(this, event, ev_data_))
|
|
return 1; // Local handler consumed the event
|
|
}
|
|
return T::handle(event); // Try the default handler
|
|
}
|
|
}
|
|
void draw() override {
|
|
if constexpr (!is_same<T, Fl_Widget>::value) {
|
|
if (super_draw && super_draw_first)
|
|
T::draw();
|
|
}
|
|
if (inner_drawer)
|
|
inner_drawer(this, draw_data_);
|
|
else {
|
|
}
|
|
if constexpr (!is_same<T, Fl_Widget>::value) {
|
|
if (super_draw && !super_draw_first)
|
|
T::draw();
|
|
}
|
|
}
|
|
|
|
~Widget_Derived() {
|
|
if (deleter) {
|
|
deleter(this, deleter_data_);
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif
|