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; }