Fl_Gl_Windowでのキーボード・マウス入力†
Fl_Gl_Windowの派生クラスによるOpenGL描画にキーボード・マウスイベントを処理する関数を追加する.
クラスの宣言†
rxFlGLWindowクラスを以下のように変更する.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| | class rxFlGLWindow : public Fl_Gl_Window
{
enum DrawObject
{
RX_IDD_VERTEX = 0, RX_IDD_EDGE, RX_IDD_FACE, };
int m_iDraw; rxTrackball m_tbView;
public:
rxFlGLWindow(int x_, int y_, int w_, int h_, const char* l)
: Fl_Gl_Window(x_, y_, w_, h_, l)
{
m_iDraw = RX_IDD_FACE;
resizable(this); end();
}
virtual ~rxFlGLWindow()
{
}
public:
void InitGL(void);
void Resize(int w, int h);
void Display(void);
void Mouse(int button, int state, int x, int y);
void Motion(int x, int y);
void PassiveMotion(int x, int y);
void Keyboard(int key, int x, int y);
private:
void draw(void)
void resize(int x_, int y_, int w_, int h_);
int handle(int ev);
};
|
キーボード・マウスなどによるイベントを受け取るために,handle関数をオーバーライドしている.
そして,GLUTからの移植性を考えて,Mouse,Motion,PassiveMotion,Keyboard関数を追加している.
また,マウスにドラッグによる視点の変更を行うためのトラックボールクラス,
rxTrackball m_tbView;
キーボードによる描画の変更のためのフラグ
enum DrawObject
{
RX_IDD_VERTEX = 0, //!< 頂点描画
RX_IDD_EDGE, //!< エッジ描画
RX_IDD_FACE, //!< 面描画
};
int m_iDraw; //!< 描画フラグ
をメンバ変数として追加した.
イベントハンドラ†
handle関数では様々なFLTKイベントが発生したときに呼ばれる.
イベントの種類は引数evで受け取ることができる.
各イベントの詳細は次節以降参照.
OpenGLのためのイベントハンドラの例を以下に示す.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| | int rxFlGLWindow::handle(int ev)
{
switch(ev){
case FL_PUSH: Mouse(Fl::event_button(), 1, Fl::event_x(), Fl::event_y());
break;
case FL_RELEASE: Mouse(Fl::event_button(), 0, Fl::event_x(), Fl::event_y());
break;
case FL_DRAG: Motion(Fl::event_x(), Fl::event_y());
break;
case FL_MOVE: PassiveMotion(Fl::event_x(), Fl::event_y());
break;
case FL_KEYDOWN: Keyboard(Fl::event_key(), Fl::event_x(), Fl::event_y());
break;
case FL_KEYUP: case FL_SHORTCUT: break;
case FL_FOCUS: case FL_UNFOCUS:
break;
default:
return Fl_Window::handle(ev);
}
return 1;
}
|
FLTKは直近のイベントに関する情報を変数に記憶しておく.これらの変数の値を参照するのが,
Fl::event_x(),
Fl::event_y(),
Fl::event_button()や
Fl::event_key()などである.
これらFl::event_*()関数を使って,様々な値を実際に処理を行う関数に渡している.
各イベントの詳細は以下参照.
マウスイベント†
rxFlGLWindowクラスにおいて,これらのイベントを処理する関数の例を以下に示す.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| | void Mouse(int button, int state, int x, int y)
{
make_current();
int keymod = (Fl::event_state(FL_SHIFT) ? 2 : (Fl::event_state(FL_CTRL) ? 3 : 1));
if(button == FL_LEFT_MOUSE){
if(state){
m_tbView.Start(x, y, keymod);
}
else{
m_tbView.Stop(x, y);
}
}
else if(button == FL_MIDDLE_MOUSE){
}
else if(button == FL_RIGHT_MOUSE){
}
redraw();
}
void Motion(int x, int y)
{
make_current();
m_tbView.Motion(x, y);
redraw();
}
void PassiveMotion(int x, int y)
{
}
|
マウスボタンの状態はFL_*_MOUSEという名前で定義されている.
m_tbView.Start()はトラックボールでの回転・平行移動・ズームをスタートする.
第三引数の値が1で回転,2で平行移動(視線に垂直な方向に平行移動),3でズーム(視線方向に平行移動)である.
ドラッグ中に呼ばれるMotion関数内で,m_tbView.Motion()により視点回転・移動処理を行い,
マウスボタンが放されたら m_tbView.Stop()で処理を終了している.
キーボードイベント†
イベントID | イベント発行タイミング | 関連する関数 |
FL_KEYDOWN | キーボードダウン.ウィジットにフォーカスがあるときに使われる. | Fl::event_key()(ASCIIコード) Fl::event_text()(文字列 - char*) Fl::event_length()(文字列の長さ) |
FL_KEYBOARD | FL_KEYDOWNと同じ | 同上 |
FL_KEYUP | キーボードアップ.ウィジットにフォーカスがあるときに使われる. | 同上 |
FL_SHORTCUT | グローバルショートカット.どのウィジットにもフォーカスがなかったときに発行される. | 同上 |
rxFlGLWindowクラスにおいて,これらのイベントを処理する関数の例を以下に示す.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| | void Keyboard(int key, int x, int y)
{
cout << "Keyboard" << endl;
make_current();
switch(key){
case FL_Left:
m_iDraw = (m_iDraw == RX_IDD_VERTEX ? RX_IDD_FACE : m_iDraw-1);
break;
case FL_Right:
m_iDraw = (m_iDraw == RX_IDD_FACE ? RX_IDD_VERTEX : m_iDraw+1);
break;
case 'v':
m_iDraw = RX_IDD_VERTEX;
break;
case 'e':
m_iDraw = RX_IDD_EDGE;
break;
case 'f':
m_iDraw = RX_IDD_FACE;
break;
}
redraw();
}
|
Keyboard関数では頂点,エッジ,面描画を切り替える.
矢印左右でこれらの描画を順次切り替え,
キー"V","E","F"で直接それぞれの描画を設定する.
ウィンドウフォーカスイベント†
イベントID | イベント発行タイミング | 関連する関数 |
FL_ENTER | マウスポインタがウィジット上に来たとき | - |
FL_LEAVE | マウスポインタがウィジット上から外れたとき | - |
FL_FOCUS | ウィジットにキーボードフォーカスが来たとき | - |
FL_UNFOCUS | ウィジットからキーボードフォーカスが外れたとき | - |
ウィジットイベント†
イベントID | イベント発行タイミング | 関連する関数 |
FL_ACTIVATE | ウィジットがアクティブになった(activate()が呼ばれた)とき | - |
FL_DEACTIVATE | ウィジットがアクティブでなくなった(deactivate()が呼ばれた)とき | - |
FL_SHOW | show()が呼ばれてウィンドウが可視化されたとき | - |
FL_HIDE | hide()が呼ばれてウィンドウが不可視化されたとき | - |
クリップボードイベント†
D&Dイベント†
FLTKはファイルやテキストのD&Dに対応している.
テキストはUFT8エンコードで送られ,ファイルはフルパスのリストとして送られる.
これらは上記FL_PASTEイベント後,
Fl::event_text()(文字列 - char*),Fl::event_length()(文字列の長さ)
を参照することでその情報が得られる.
イベントID | イベント発行タイミング | 関連する関数 |
FL_DND_ENTER | ドラッグしたマウスポインタがウィジット上に来たとき | - |
FL_DND_DRAG | ドラッグ中に呼ばれる | - |
FL_DND_LEAVE | ドラッグしたマウスポインタがウィジット上から外れたとき | - |
FL_DND_RELEASE | マウスボタンをリリースして,ファイルやテキストをドロップしたとき.この後すぐにFL_PASTEが呼ばれる | - |
ソースコード†
上記例のソースコードは以下(Viual Studio 2010用プロジェクトファイル含む).
実行結果は以下.