## 4.2如何开发一个控件的子类
你的子类可以直接继承Fl_Widget 类,也可以继承任何Fl_Widget类的子类。Fl_Widget只有四个虚拟函数,子类必须重载所有的或部分的这些函数。
### 构造函数
构造函数应该有以下参数
```
MyClass(int x, int y, int w, int h, const char *label = 0);
```
这就允许该类能很好的应用于FLUID中
这个构造函数必须调用基类的构造函数并传递相同的参数
```
MyClass::MyClass(int x, int y, int w, int h, const char *label):
Fl_Widget(x, y, w, h, label) {// do initialization stuff...}
```
Fl_Widget的保护构造函数通过传递的参数x,y,w,h,label分别设置x(),y(),w(),h()和label()并初始化其他的属性如:
```
type(0);
box(FL_NO_BOX);
color(FL_BACKGROUND_COLOR);
selection_color(FL_BACKGROUND_COLOR);
labeltype(FL_NORMAL_LABEL);
labelstyle(FL_NORMAL_STYLE);
labelsize(FL_NORMAL_SIZE);
labelcolor(FL_FOREGROUND_COLOR);
align(FL_ALIGN_CENTER);
callback(default_callback,0);
flags(ACTIVE|VISIBLE);
image(0);
deimage(0);
```
### Fl_Widget的保护成员函数
以下的成员函数是Fl_Widget提供给子类的:
```
Fl_Widget::clear_visible
Fl_Widget::damage
Fl_Widget::draw_box
Fl_Widget::draw_focus
Fl_Widget::draw_label
Fl_Widget::set_flag
Fl_Widget::set_visible
Fl_Widget::test_shortcut
Fl_Widget::type
void Fl_Widget::damage(uchar mask)
void Fl_Widget::damage(uchar mask, int x, int y, int w, int h)
uchar Fl_Widget::damage()
```
第一个函数是指对象的部分需要更新。参数mask中的位设置传递给damage().draw()函数能根据该值得到哪些需要重画。公共成员函数Fl_Widget::redraw()只是简单的做Fl_Widget::damage(FL_DAMAGE_ALL),即所有的都重画,但是你的控件真正执行的时候会调用私有成员函数damage(n).
第二个函数指某个区域无效,需要重画。
第三个函数返回所有damage(n)的调用所产生的位。
当重新画一个控件时,你应该先看看无效位,再决定你的控件的哪部分需要重新画。Handle()函数能够设置单独的无效位限制需要重画的数量。
```
MyClass::handle(int event)
{
if (change_to_part1) damage(1);
if (change_to_part2) damage(2);
if (change_to_part3) damage(4);
}
MyClass::draw()
{
if(damage() & FL_DAMAGE_ALL)
{
... draw frame/box and other static stuff ...
}
if (damage() & (FL_DAMAGE_ALL | 1)) draw_part1();
if (damage() & (FL_DAMAGE_ALL | 2)) draw_part2();
if (damage() & (FL_DAMAGE_ALL | 4)) draw_part3();
}
void Fl_Widget::draw_box() const
```
第一个函数根据该控件的尺度画他的box().第二个函数根据box的类型b ,颜色c画box.
```
void Fl_Widget::draw_focus() const
void Fl_Widget::draw_focus(Fl_Boxtype b, int x, int y, int w, int h) const
```
在一个空间的限制box中画出焦点筐。第二个函数允许指定另一个不同box来画焦点
```
Fl_Widget::draw_label() const
void Fl_Widget::draw_label(int x, int y, int w, int h) const
void Fl_Widget::draw_label(int x, int y, int w, int h, Fl_Align align) const
```
Draw()函数调用该函数来画一个控件的label,如果标签出了该控件的box 范围,将不会被画出。
第二种形式自定义一个box来画标签,比如用于移动的滑块
第三种形式可以将标签画在任意的地方
```
void Fl_Widget::set_visible()
void Fl_Widget::clear_visible()
```
与Fl_Widget::show() Fl_Widget::hide()作用相同,但不发送FL_SHOW,FL_HIDE事件。
```
int Fl_Widget::test_shortcut() const
static int Fl_Widget::test_shortcut(const char *s)
uchar Fl_Widget::type() const
void Fl_Widget::type(uchar t)
```
返回一个8位的标示符,用于与Forms兼容,你也可以同于其他任何目的,设置的值应该小于100,以免与系统的保留值冲突
- 第一章:FLTK编程模型
- 1.1FLTK功能简介
- 1.2搭建FLTK开发环境
- 1.3FLTK构件简介
- 1.4FLTK事件处理
- 1.5FLTK消息处理
- 1.6OpenGL编程
- 第二章:常用的控件和属性
- 2.1按钮
- 2.2文本
- 2.3颜色
- 2.4Box类型
- 第三章:FLTK的画图函数
- 3.1何时可以画图
- 3.2 FLTK的画图函数
- 3.3剪切
- 3.4颜色
- 3.5设置线条的属性
- 3.6画一般的图形函数
- 3.7画封闭的线,一次连接个顶点
- 3.8画三边形或四边形,并填充内部
- 3.9复杂图形函数
- 3.10字体
- 3.11覆盖画图函数
- 第四章:在FLTK中自定义控件
- 4.1定制图形控件说明
- 4.2如何开发一个控件的子类
- 4.3处理事件
- 4.4画控件