MIRACLE
メールサービス申込 ユーザー登録 パートナー情報
お問い合わせ FAQ サイトマップ
MIRACLE LINUXの特長 製品紹介 サービス案内 購入 サポート 技術フォーラム

« 1度だけboot | メイン | ダンプ解析は誰のものか »

2006年6月30日 (金)

タブをつくる

タブと聞くとあなたは、「4文字スペース空けるやつ」と、「GUIのウィンドウを構成するパーツで、FireFoxとかのタブブラウザみたいなもの」のどちらをイメージしますか?
私はどちらかというと「スペース空けるやつ」をイメージする側ですが、今日は、GUI側のお話です。
X WindowでGUIを構成するときに利用されるOpenMotifでもタブを使うことができます。
-----
$ man XmTabStack
XmTabStack(3X)                                                 XmTabStack(3X)

NAME
       XmTabStack - The TabStack widget class

SYNOPSIS
       #include <Xm/TabStack.h>

DESCRIPTION
       The  XmTabStack  widget  manages a group of widgets such that only one
       widget in the group is visible at a time.  Each  child  is  associated
       with  a "tab" that displays a text label and/or a pixmap. By selecting
       the "tab" the user interactively determines which child is  displayed.
       This widget exhibits behavior similar to the Microsoft Windows(TM) Tab
       Control.
....
-----
といった形で説明があります。

普通の開発者の立場だと、このウィジェットを利用して、いろいろなGUIのコンポーネントを作成すると思います。
ですが、今日はちょっと視点を変えて、このタブがOpenMotifの中でどのように作られているのか見てみたいと思います。

タブを使うと、このようなGUIのウィンドウを作ることができます。

Tab1_2

タブの表示に関わっているのは、OpenMotifのlib/Xm/TabStack.c、TabBox.cのあたりのソースです。
TabStack.cは、タブのパーツのうち、下半分の表示を担っています。

そして、今日のメインは、TabBox.cで、このソースが、タブの切り替えに使う上半分のタブの部分の処理を行っています。

X Windowでは、隠されていたウィンドウが前面に出されて表示されるとき、Exposeというイベントが発生します。

TabBox.cでは、それぞれのイベントが発生したときに呼び出される関数が定義されていますが、そのうちexposeイベントには、"Redisplay()"という関数が定義されています。

------

    /* destroy            */    NULL,
    /* resize             */    NULL,
    /* expose             */    Redisplay,
    /* set_values         */    NULL,
    /* set values hook    */    NULL,
-------

つまり、ウィンドウの再描画は、このRedisplay()で行われているということが分かりますので、Redisplay()を見ていくことにします。

で、早速、Redisplay()の動作をおおざっぱに書くと、

------
Redisplay()
  ->   Redisplaytabs()
     ->       DrawTab()

------

となっていることが分かります。

RedisplayTabs()の中を見てみると、次のようになっています。

-----

    geom = XmTabBox__actual(tab);
    for( i = 0; i < count; ++i )
    {
        if( XiRectInRegion(region, geom[i].x, geom[i].y, geom[i].width,
                           geom[i].height) )
        {
            info = _XmTabbedStackListGet(XmTabBox_tab_list(tab), i);

            DrawTab(tab, info, &(geom[i]),
                    (Boolean)(XmTabBox__selected(tab) == i),
                    (Boolean)(XmTabBox__keyboard(tab) == i));
        }
    }
-----

countには、タブが何個あるか入っています。つまりfor文で、タブの数だけループをまわして、それぞれのタブに対して、DrawTab()を呼び出しているのです。

ただし注意点として、DrawTab()を呼び出す前に、XiRectInRegion()で、そのタブが、再描画の必要な領域にあるかどうか確認しています。
なので、もともと他のウィンドウに隠されていなかったタブに関しては、改めて再描画はされないということです。

次回は、実際のDrawTab()の処理を見てみたいと思います。

トラックバック

このページのトラックバックURL:
http://www.typepad.jp/t/trackback/4447/2773571

このページへのトラックバック一覧 タブをつくる:

コメント

コメントを投稿

コメントは記事の投稿者が承認するまで表示されません。

会社情報 採用情報 個人情報保護方針 商標等取り扱い事項 English
Copyright(c)2000-2006 MIRACLE LINUX CORPORATION. All Rights Reserved.