## 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畫控件