日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

第七章 在FLTK中自定義控件

 Delores 2007-12-04

新控件的創(chuàng)建是通過繼承已經(jīng)存在的控件來得到的,一般控件繼承Fl_Widget得到,組合控件繼承Fl_Group得到

一個(gè)普通控件一般通過接收和顯示一個(gè)值來與用戶交互

一個(gè)組合控件包含一組子控件并處理子控件的移動(dòng),改變大小,顯示或隱藏事件。Fl_Group是所有組合控件的基類,其他組合控件比如Fl_Pack, Fl_Scroll, Fl_Tabs , Fl_Tile,  Fl_Window都是他的子類

你也可以通過繼承其他的已存在控件來得到你要的控件,通過提供不同的外觀和接口。比如Button 控件都是 Fl_Button類的子類。他們的共同點(diǎn)是都是通過鼠標(biāo)點(diǎn)擊事件與用戶交互。唯一不同的是按鈕的外觀。

如何開發(fā)一個(gè)控件的子類

你的子類可以直接繼承Fl_Widget 類,也可以繼承任何Fl_Widget類的子類。Fl_Widget只有四個(gè)虛擬函數(shù),子類必須重載所有的或部分的這些函數(shù)。

構(gòu)造函數(shù)

構(gòu)造函數(shù)應(yīng)該有以下參數(shù)

MyClass(int x, int y, int w, int h, const char *label = 0);

這就允許該類能很好的應(yīng)用于FLUID

這個(gè)構(gòu)造函數(shù)必須調(diào)用基類的構(gòu)造函數(shù)并傳遞相同的參數(shù)

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的保護(hù)構(gòu)造函數(shù)通過傳遞的參數(shù)x,y,w,h,label分別設(shè)置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的保護(hù)成員函數(shù)

以下的成員函數(shù)是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()

第一個(gè)函數(shù)是指對(duì)象的部分需要更新。參數(shù)mask中的位設(shè)置傳遞給damage().draw()函數(shù)能根據(jù)該值得到哪些需要重畫。公共成員函數(shù)Fl_Widget::redraw()只是簡(jiǎn)單的做Fl_Widget::damage(FL_DAMAGE_ALL),即所有的都重畫,但是你的控件真正執(zhí)行的時(shí)候會(huì)調(diào)用私有成員函數(shù)damage(n).

第二個(gè)函數(shù)指某個(gè)區(qū)域無效,需要重畫。

第三個(gè)函數(shù)返回所有damage(n)的調(diào)用所產(chǎn)生的位。

 

當(dāng)重新畫一個(gè)控件時(shí),你應(yīng)該先看看無效位,再?zèng)Q定你的控件的哪部分需要重新畫。Handle()函數(shù)能夠設(shè)置單獨(dú)的無效位限制需要重畫的數(shù)量。

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

第一個(gè)函數(shù)根據(jù)該控件的尺度畫他的box().第二個(gè)函數(shù)根據(jù)box的類型b ,顏色cbox.

 

void Fl_Widget::draw_focus() const
void Fl_Widget::draw_focus(Fl_Boxtype b, int x, int y, int w, int h) const

在一個(gè)空間的限制box中畫出焦點(diǎn)筐。第二個(gè)函數(shù)允許指定另一個(gè)不同box來畫焦點(diǎn)

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()函數(shù)調(diào)用該函數(shù)來畫一個(gè)控件的label,如果標(biāo)簽出了該控件的box 范圍,將不會(huì)被畫出。

第二種形式自定義一個(gè)box來畫標(biāo)簽,比如用于移動(dòng)的滑塊

第三種形式可以將標(biāo)簽畫在任意的地方

 

void Fl_Widget::set_visible()
void Fl_Widget::clear_visible()

Fl_Widget::show() Fl_Widget::hide()作用相同,但不發(fā)送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)

返回一個(gè)8位的標(biāo)示符,用于與Forms兼容,你也可以同于其他任何目的,設(shè)置的值應(yīng)該小于100,以免與系統(tǒng)的保留值沖突

處理事件

虛擬函數(shù)int handle(int event)被用來處理任何發(fā)送給控件的事件.他能:

改變控件的狀態(tài)

調(diào)用Fl_Widget::redraw()如果該控件需要重新顯示

調(diào)用Fl_Widget::damage(n)當(dāng)控件需要部分更新時(shí)(假如你在Fl_Widget::draw()函數(shù)中提供了對(duì)該函數(shù)的支持)

調(diào)用Fl_Widget::do_callback()如果一個(gè)回調(diào)函數(shù)產(chǎn)生時(shí).

調(diào)用Fl_Widget::handle()對(duì)子控件

事件用一個(gè)整數(shù)來標(biāo)識(shí).最近事件產(chǎn)生的其他消息靜態(tài)存儲(chǔ)在本地,調(diào)用Fl::event_*()可以得到.

以下是一個(gè)利用handle()處理事件的例子,該控件的行為類似按鈕同時(shí)接收x按鍵并調(diào)用回調(diào)函數(shù)

int MyClass::handle(int event) {

  switch(event) {

    case FL_PUSH:

      highlight = 1;

      redraw();

      return 1;

    case FL_DRAG: {

        int t = Fl::event_inside(this);

        if (t != highlight) {

          highlight = t;

         redraw();

       }

      }

      return 1;

    case FL_RELEASE:

      if (highlight) {

       highlight = 0;

       redraw();

        do_callback();

       // never do anything after a callback, as the callback

       // may delete the widget!

      }

      return 1;

    case FL_SHORTCUT:

      if (Fl::event_key() == 'x') {

        do_callback();

       return 1;

      }

      return 0;

    default:

      return Fl_Widget::handle(event);

  }

}

 

當(dāng)你的handle()函數(shù)處理某事件后不能返回0,若是返回0,父控件將會(huì)把該事件發(fā)送給其他控件。

 

 

畫控件

當(dāng)FLTK需要重畫控件時(shí)將調(diào)用虛擬函數(shù)draw().只有在damage()返回非0值時(shí)調(diào)用該函數(shù),draw()返回后,damage()被清0。Draw()應(yīng)該被聲明為保護(hù)成員函數(shù),避免在不需要寫畫圖代碼時(shí)用到。

Damage()將包含從最后一次調(diào)用draw()damage(n)調(diào)用產(chǎn)生的所有與或位信息,根據(jù)該信息只重畫需要重畫的位置,只有FLTK認(rèn)為需要全部重畫時(shí)才打開FL_DAMAGE_ALL位,比如收到expose事件。

修改控件的尺寸

resize(int x,int y,int w,int h)在控件被移動(dòng)和改變大小時(shí)被調(diào)用,這些參數(shù)分別是新位置,寬度和高度。但是x(),y(),w(),h(),還是以前的值,若要改變這些值,必須在基類中也調(diào)用resize()函數(shù)

不需要調(diào)用redraw()函數(shù),至少只改變x(),y()時(shí)不需要,因?yàn)橐粋€(gè)組合控件有一套更有效的方法來畫新的位置

如何制作一個(gè)組合控件

一個(gè)組合控件包括一個(gè)或多個(gè)子控件。制作組合控件必須繼承Fl_Group.不繼承Fl_Group類當(dāng)然也可能可以制作一個(gè)組合控件,但是你還是要重新寫Fl_Group類里面的工作

子控件可能在類里面聲明

class MyClass : public Fl_Group {

  Fl_Button the_button;

  Fl_Slider the_slider;

  ...

};

 

構(gòu)造函數(shù)要初始化這些子控件。他們將被自動(dòng)的add()group中。因?yàn)?/span>Fl_Group構(gòu)造函數(shù)調(diào)用了begin().在構(gòu)造函數(shù)中不要忘記調(diào)用end()函數(shù)

MyClass::MyClass(int x, int y, int w, int h) :

  Fl_Group(x, y, w, h),

  the_button(x + 5, y + 5, 100, 20),

  the_slider(x, y + 50, w, 20)

{

  ...(you could add dynamically created child widgets here)...

  end(); // don't forget to do this!

}

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多