Lesson 5:リストビュー


 前回に続き、今回も軽めの内容で、リストを作ってみましょう。

 リストを作るのに使用するクラスが「BListView」なのは、BeBookですぐ調べられるでしょう。
 今回は、リストビューを2つ作り、一つは単項目のみ選択できるようにし、もう一つは複数項目の選択ができるようにします。
 前回と同じように、ボタンを押すと、選択状況がストリングビューに表示されるようにしましょう。

 今回のプログラムも簡単なので、いきなり全部やってしまいましょう。(今回のプログラムは、前回のプログラムに酷似していますので。 前回のプロジェクトをコピーして作成すると楽です。)

/**** ファイル名 : BaseApp.h ****/

#ifndef BASEAPP
#define BASEAPP
//---------------------------------------------------------------------
#include <Be.h>
#include "MainWindow.h"
//---------------------------------------------------------------------
#define APPLICATION_SIGNATURE "application/x-vnd.vow-be3rdapp"
//---------------------------------------------------------------------
class BaseApp : public BApplication
{
public:
    BaseApp()
        :BApplication(APPLICATION_SIGNATURE)
    {
        BAppMainWindow *mainwnd=new BAppMainWindow(
            BRect(MAINWINDOW_POSITION_LEFT,MAINWINDOW_POSITION_TOP,
                  MAINWINDOW_POSITION_WIDTH+MAINWINDOW_POSITION_LEFT-1,
                  MAINWINDOW_POSITION_HEIGHT+MAINWINDOW_POSITION_TOP-1),
            MAINWINDOW_TITLE);
        mainwnd->Show();
    };
};
//---------------------------------------------------------------------
#endif

/**** ファイル名 : MainWindow.h ****/

#ifndef MAINWINDOW
#define MAINWINDOW
//---------------------------------------------------------------------
#include <Be.h>
//---------------------------------------------------------------------
#define MAINWINDOW_TITLE            "ListView,ScrollView Application"
#define MAINWINDOW_POSITION_LEFT    100
#define MAINWINDOW_POSITION_TOP     100
#define MAINWINDOW_POSITION_WIDTH   400
#define MAINWINDOW_POSITION_HEIGHT  220
#define MAINWINDOW_WINDOWSTYLE      (B_TITLED_WINDOW)
//---------------------------------------------------------------------
#define MSG_SET 'setb'

//---------------------------------------------------------------------
class BAppMainView : public BView
{
public:
    BStringView *strview;
    BListView *lstview1,*lstview2;

    BAppMainView(BRect frame);
};
//---------------------------------------------------------------------
class BAppMainWindow : public BWindow
{
private:
    void SetStrView(void);
public:
    BAppMainView *mainview;
    //-----------------------------------------------------------------
    BAppMainWindow(BRect frame,const char *title);
    virtual void MessageReceived(BMessage *msg);
    //-----------------------------------------------------------------
    bool QuitRequested()
    {
        be_app->PostMessage(B_QUIT_REQUESTED);
        return true;
    };
};
//---------------------------------------------------------------------
#endif

/**** ファイル名 : MainWindow.cpp ****/

//---------------------------------------------------------------------
#include "MainWindow.h"
//---------------------------------------------------------------------
BAppMainWindow::BAppMainWindow(BRect frame,const char *title)
    :BWindow(frame,title,MAINWINDOW_WINDOWSTYLE,0)
{
    mainview=new BAppMainView(Bounds());	
    AddChild(mainview);
}
//---------------------------------------------------------------------
void BAppMainWindow::SetStrView(void)
{
    char wk[256];
    int idx=0;
			
    sprintf(wk,"List A=%d,List B=",
                (int)mainview->lstview1->CurrentSelection(0));
			
	for(int i=0;idx!=-1;i++)
	{
        char wk1[10];

        idx=(int)mainview->lstview2->CurrentSelection(i);
        sprintf(wk1,"%d,",idx);
        strcat(wk,wk1);				
    };
			
    mainview->strview->SetText(wk);
}
//---------------------------------------------------------------------
void BAppMainWindow::MessageReceived(BMessage *msg)
{
    switch(msg->what)
    {
        case MSG_SET:
            SetStrView();
            break;
        default:
            BWindow::MessageReceived(msg);
    }
}
//---------------------------------------------------------------------
BAppMainView::BAppMainView(BRect frame)
    :BView(frame,"bappmainview",B_FOLLOW_ALL,B_WILL_DRAW)
{
    BRect viewrect(Bounds());
    char listitems[][10]=
        {"ITEM_1","ITEM_2","ITEM_3","ITEM_4","ITEM_5",
         "ITEM_6","ITEM_7","ITEM_8","ITEM_9","ITEM_10"};
		 	
    BMessage *setmsg=new BMessage(MSG_SET);
    BButton *btn=
        new BButton(BRect(viewrect.right-68,188,viewrect.right-8,200),
                    "btn1","SET!!",setmsg);
    AddChild(btn);
	
    strview=new BStringView(BRect(8,188,viewrect.right-70,200),
                            "strview","No Data");
    AddChild(strview);

    lstview1=new BListView(BRect(8,8,
                                 viewrect.right-8-B_V_SCROLL_BAR_WIDTH,
                                 90),"list1");
    BScrollView *scr=new BScrollView("scroll1",lstview1,
                                     B_FOLLOW_LEFT | B_FOLLOW_TOP,
                                     0,false,true);
    AddChild(scr);
    for(int i=0;i<10;i++)
        lstview1->AddItem(new BStringItem(listitems[i]));

    lstview2=new BListView(BRect(8,98,viewrect.right-8-B_V_SCROLL_BAR_WIDTH,
                                 180),"list2",B_MULTIPLE_SELECTION_LIST);
    scr=new BScrollView("scroll2",lstview2,
                                     B_FOLLOW_LEFT | B_FOLLOW_TOP,
                                     0,false,true);
    AddChild(scr);
    for(int i=0;i<10;i++)
        lstview2->AddItem(new BStringItem(listitems[i]));
}
//---------------------------------------------------------------------

/**** ファイル名 : main.cpp ****/

//---------------------------------------------------------------------
#include "BaseApp.h"
//---------------------------------------------------------------------
int main(void)
{
    new BaseApp();
    be_app->Run();
    delete be_app;
    return true;
}
//---------------------------------------------------------------------

 BMainAppViewクラスのコンストラクタと、ボタンが押された際に、MessageReceived関数内で呼ばれるSetStrView関数を見てみましょう。

 BMainAppViewのコンストラクタでは、各ビューの作成を行っています。

 コンストラクタの中で、listitemsという配列を宣言して、"Item1"〜"Item10"までの文字列で初期化しています。この文字列をリストの内容にします。(二つのリストは同じ内容。)
 ボタンやストリングビューはいつも通りの作り方なので、問題無いでしょう。問題なのは、リストビューの作り方です。
    lstview1=new BListView(BRect(8,8,
                                 viewrect.right-8-B_V_SCROLL_BAR_WIDTH,
                                 90),"list1");
    BScrollView *scr=new BScrollView("scroll1",lstview1,
                                     B_FOLLOW_LEFT | B_FOLLOW_TOP,
                                     0,false,true);
    AddChild(scr);
 lstview1の実態をBListViewのコンストラクタに位置と名前を渡して作成しているのは他のビューと同じです。違うのは、lstview1をAddChildしていない点です。
 lstview1をいきなりAddChildすることもできるのですが、これだと、リストビューにスクロールバーや枠線が表示されません。 そこで、スクロールバーを提供いしてくれるBScrollViewを作成して、そのターゲットにlstview1を登録しています。 (スクロールビューのコンストラクタの2番目の引数にlstview1を渡しているでしょ。)
 あとは、BListViewクラスのAddItem関数でlistitemsの文字列を登録していけば、リストビューの完成です。 (listitemsをBStringItemクラスにして渡している事に注意)
 同じようにlstview2も作成しますが、こちらはBListViewのコンストラクタの3番目の引数にB_MULTIPLE_SELECTION_LISTと指定しています。 こうすることで、このリストは複数の項目を選択することができるようになります。

 次にボタンが押された際のSetStrViewの中身ですが、これは二つのリストの選択状況を 「List1=xx ,List2=xx,xx,・・・,-1」と表示します。
 SetStrViewの中をもう一度見てみましょう。
    sprintf(wk,"List1=%d,List2=",
                (int)mainview->lstview1->CurrentSelection(0));
			
    for(int i=0;idx!=-1;i++)
    {
        char wk1[10];

        idx=(int)mainview->lstview2->CurrentSelection(i);
        sprintf(wk1,"%d,",idx);
        strcat(wk,wk1);				
    };
			
    mainview->strview->SetText(wk);
 まず、最初のsprintfで、lstview1の選択状況とList2の見出しを作成しています。
 BListViewの選択状況はメンバ関数のCurrentSelectionで求めることができます。 CurentSelectionの引数には何番目の選択項目かを指定します。(最初の値は0です。) もし指定された順番の選択項目がなければ-1を返します。
 lstview1は一つの項目しか選択できないので、1番目の選択項目(番号は0)だけを調べれば良いので、 CurrentSelection(0)で調べることができます。
 lstview2は複数選択できますが、CurrentSelectionに渡す値を一つずつずらして、 -1になるまで調べていけば、全ての選択項目を求めることができますので、ループして調べます。

 後は実際に動かして、lstview2が複数の項目を選択できることや、 ボタンを押して、選択状況を取得できる個とを確かめてください。

 今回も簡単な内容でした。次回はテキストビューに挑戦しますが、これもたぶん簡単にできるでしょう。 問題は、その次のメニューですね・・・。
 さて、次の準備もしなくっちゃ。

ソースリスト
圧縮ファイル
R5 Intel環境で確認
Be3rdApp19991214.zip
ソースファイル
BaseApp.h
main.cpp
MainWindow.cpp
MainWindow.h

次の項目へ

トップページへ戻る