ホーム > 製品情報 > SophiaFramework UNIVERSE > チュートリアル > BREW RSS リーダー

RSS リーダー 〜 HTTP と XML の BREW C++ プログラミング 〜

画面描画

RSS アイテムのタイトル ( title ) と説明 ( description ) を表示するメイン画面です。

MainWindow の定義

SFMTYPEDEFCLASS(MainWindow)
class MainWindow : public SFRTitleWindow {
    SFMSEALCOPY(MainWindow)
private:
    SInt16 _displine; // 表示する行の先頭
    SInt16 _cursor;   // カーソル位置
    SInt16 _maxline;  // 表示する行数
public:
    MainWindow(SInt16 softkeyHeight);
    static Void SetSoftkey(Void);
private:
    HANDLER_DECLARE_VOIDRENDER(OnRenderContent) // 描画ハンドラの宣言
    HANDLER_DECLARE_BOOLEVENT(OnKey)            // キーハンドラの宣言
};

MainWindow の描画ハンドラ

HANDLER_IMPLEMENT_VOIDRENDER(MainWindow, OnRenderContent, graphics)
{
    //画面サイズを取得
    SFXRectangle rectangle(GetContentWorld());
    SFXRGBColor forecolor;
    SFXRGBColor backcolor;
    SIntN i;
    RSSFeedPtr current;

    SInt16 height = graphics->GetFontHeight(); // フォントの高さを取得
    SInt16 bottom = rectangle.GetBottom(); // 今の長方形の底辺を覚えておく
    rectangle.SetHeight(height); // rectangle の高さをフォントの高さに設定

    // 親ハンドラの呼び出し (画面のクリアー)
    SFRTitleWindow::ContentHandler(graphics);

    // アプリクラスから現在のフィードを取得
    current = RssReader::GetCurrentFeed();

    // 行の描画処理
    for (i = _displine;  i < _displine + _maxline ; ++i) {
        if (i - _displine == _cursor) { // カーソルのある行なら
            // 色を変える
            forecolor.Set(0xff, 0xff, 0xff, 0x00);
            backcolor.Set(0x66, 0x66, 0xff, 0x00);
        }
        else {
            forecolor.Set(0x00, 0x00, 0x00, 0x00);
            if (i % 2 == 0) { // 偶数行目と奇数行目で色を変える
                backcolor.Set(0xdd, 0xdd, 0xff, 0);
            } else {
                backcolor.Set(0xee, 0xee, 0xff, 0);
            }
        }
        // アイテムのタイトルの背景となる長方形を描く
        graphics->FillRectangle(rectangle, backcolor);
        graphics->SetForeColor(forecolor);
        if (current != null &&
                i < current->GetSize()) {
            if (current->GetItem(i)->title.IsEmpty()) {
                // i番目のitem のタイトル文字列を描く
                graphics->DrawText("[無題]",
                    rectangle,
                    IDF_ALIGN_LEFT | IDF_ALIGN_MIDDLE);
            } else {
                if (current->GetItem(i)->alreadyRead) {
                    // i番目のitem のタイトル文字列を描く
                    graphics->DrawText(
                        current->GetItem(i)->title,
                        rectangle,
                        IDF_ALIGN_LEFT | IDF_ALIGN_MIDDLE);
                } else {
                    graphics->SetFont(AEE_FONT_BOLD); // フォントを Bold にする
                    // i番目のitem のタイトル文字列を描く
                    graphics->DrawText(
                        current->GetItem(i)->title,
                        rectangle,
                        IDF_ALIGN_LEFT | IDF_ALIGN_MIDDLE);
                    graphics->SetFont(AEE_FONT_NORMAL);
                }
            }
        }
        rectangle.AddY(height); // rectangleをheightだけ下に移動
    }
    rectangle.AddY(15);
    // rectangleの高さをフォントの高さの整数倍
    // (切れることなく画面に表示できる限界のサイズ) にする
    rectangle.SetHeight(((bottom - rectangle.GetTop()) / height) * height);
    graphics->FillRectangle(rectangle, SFXRGBColor(255, 255, 255, 0));
    graphics->SetForeColor(SFXRGBColor(0, 0, 0, 0)); //文字色
    if (current != null &&
            current->GetSize() > _displine + _cursor) {
        //_cursor の指す item の description を描く
        graphics->DrawString(
            current->GetItem(_displine + _cursor)->description,
            rectangle,
            IDF_ALIGN_LEFT | IDF_ALIGN_MIDDLE);
    }
    SFXLine line(rectangle.GetEdgeTop()); // rectangleの上辺を取得
    graphics->DrawLine(line, SFXRGBColor(128, 128, 128, 255));
    line.Unoffset(0, 10); // 線を上に10移動
    graphics->DrawLine(line, SFXRGBColor(128, 128, 128, 255));
    return;
}

キーハンドラ

HANDLER_IMPLEMENT_BOOLEVENT(MainWindow, OnKey, event)
{
    SFXRectangle rectangle;
    RSSFeedPtr current;

    switch (event.GetP16()) {
        case AVK_DOWN: // 下キーが押されたとき
            if (_cursor == _maxline - 1) { // カーソルが一番下にある場合
                ++_displine; // 表示行を下へ
            } else {
                ++_cursor; // カーソルを下へ
            }
            InvalidateContent();          // ウィンドウを再描画
            return true;
        case AVK_UP: // 上キーが押されたとき
            if (_cursor == 0) { // カーソルが一番上にある場合
                if (_displine > 0) { // 表示行を上へ動かせるなら
                    --_displine; // 表示行を上へ動かす
                    InvalidateContent(); // ウィンドウを再描画
                }
            } else {
                --_cursor; // カーソルを上へ
                InvalidateContent();     // ウィンドウを再描画
            }
            return true;  // SOFT2 キー 又は 9 キーが押されたとき 
        case AVK_SOFT2: case AVK_9:   
            // フィード管理ウィンドウを出す
            rectangle.Set(GetBaseBound());
            rectangle.AddLeftTop(SUBSURIPTION_MARGIN, SUBSURIPTION_MARGIN);
            ::new SubscriptionWindow(rectangle);
            return true;
        case AVK_SELECT:  // SELECT が押されたとき
            current = RssReader::GetCurrentFeed();
            // 未読のアイテムを既読にする
            if (current != null &&
                    current->GetSize() > _displine + _cursor) {
                current->GetItem(_displine + _cursor)->alreadyRead = true;
                InvalidateContent();
            }
            return true;
        }
    return false;
}