BREW スケジューラー 〜 BREW C++ vCalendar プログラミング 〜
キーの処理
MainWindow
![]() |
カレンダーを描画する MainWindow では、現在のカーソルの位置を SFXDate (日付) 型の変数である _cursor に記憶しています。 |
|---|
class MainWindow : public SFRPlainWindow {
private:
SFXDate _cursor; // カーソルの位置
// 以下省略
};
キーハンドラ
HANDLER_IMPLEMENT_BOOLEVENT(MainWindow, OnKey, event)
{
Bool result(false);
switch (event.GetP16()) {
case AVK_SELECT: // セレクトキーが押されたら
::new OneDayWindow(_cursor);
result = true;
break;
case AVK_LEFT:
_cursor.SubDay(1); // カーソルを左へ (1日引く)
InvalidateContent(); // 再描画
result = true;
break;
case AVK_RIGHT:
_cursor.AddDay(1); // カーソルを右へ (1日加える)
InvalidateContent(); // 再描画
result = true;
break;
case AVK_UP:
_cursor.SubDay(7); // カーソルを上へ (1週間引く)
InvalidateContent(); // 再描画
result = true;
break;
case AVK_DOWN:
_cursor.AddDay(7); // カーソルを下へ (1週間加える)
InvalidateContent(); // 再描画
result = true;
break;
}
return result;
}
OneDayWindow
![]() |
OneDayWindow は一日の全予定を表示します。 1 行目は新規データ作成用に「新規」の文字が、2 行目以降はその日のカレンダーデータの時刻と summary フィールド ( 内容 ) が表示されます。 |
|---|
SFMTYPEDEFCLASS(OneDayWindow)
class OneDayWindow : public SFRPlainWindow {
SFMSEALCOPY(OneDayWindow)
private:
SInt16 _displine; // 表示する行の先頭
SInt16 _cursor; // カーソル位置
SInt16 _maxline; // 表示する行数
SFXDateConst _date; // その日の日付
// _date の日付の先頭の VCalendar が何番目か
SInt32 _index;
// _date の日付の VCalendar の個数
SInt32 _number;
public:
OneDayWindow(SFXDateConstRef date) static_throws;
virtual ~OneDayWindow(Void);
HANDLER_DECLARE_VOIDRENDER(OnRenderContent) // 描画ハンドラ
HANDLER_DECLARE_BOOLEVENT(OnKey) // キーハンドラ
};
※ _cursor 変数 : 0 のときは「新規」、1 以上のときはその日のカレンダーデータ
キーハンドラ
HANDLER_IMPLEMENT_BOOLEVENT(OneDayWindow, OnKey, event)
{
Bool result(false);
switch (event.GetP16()) {
case AVK_CLR: // クリアー キーが押されたら、
// ウィンドウを閉じる
result = Invoke(SFXEvent(SREVT_RESPONDER_TERMINATE,
SRP16_TERMINATE_INVOKE, true));
break;
case AVK_SELECT:
if (_cursor <= 0) { //新規作成なら
::new CreateWindow(_date); // ウィンドウを生成
} else { // そうでないならカーソルが指しているデータを渡す
// カーソルが指しているデータ
VCalendarFilePtr vcal =
SyncScheduler::GetVCalCollection()->Get(
_index + _displine + _cursor - 1);
::new ModifyWindow(_date, vcal); // ウィンドウを生成
}
result = true;
break;
case AVK_DOWN:
// カーソルがデータの一番下にないなら
if (_cursor + _displine < _number) {
// カーソルが画面の一番下にあるなら
if (_cursor >= _maxline - 1) {
++_displine; // 表示行を下へ
} else {
++_cursor; // カーソルを下へ
}
}
else { // カーソルが最下段なら
// カーソルを最上段へ
_displine = 0;
_cursor = 0;
}
InvalidateContent(); // 再描画
result = true;
break;
case AVK_UP:
if (_cursor == 0) { // カーソルが一番上にあるなら
if (_displine > 0) { // 表示行を上へ動かせるなら
--_displine; // 表示行を上へ動かす
}
else { // カーソルが最上段なら
// カーソルを最下段へ
_cursor = (_number < _maxline - 1) ?
_number : _maxline - 1;
_displine = (_number > _maxline - 1) ?
(_number - _maxline + 1) : 0;
}
} else {
--_cursor; // カーソルを上へ
}
InvalidateContent(); // 再描画
result = true;
break;
}
return result;
}
DataInputWindow
![]() |
データの新規入力画面の CreateWindow とデータ修正画面の ModifyWindow は、処理内容がほとんど同じなので、どちらも DataInputWindow を継承しています。 |
|---|
SFMTYPEDEFCLASS(DataInputWindow)
class DataInputWindow : public SFRPlainWindow {
SFMSEALCOPY(DataInputWindow)
protected:
SFRBrewTextControlPtr _textHour; // 時間入力テキストコントロール
SFRBrewTextControlPtr _textMinute; // 分入力テキストコントロール
SFRBrewTextControlPtr _textContent; // 内容入力テキストコントロール
SFRButtonControlPtr _buttonOk; // OK ボタン
SFRButtonControlPtr _buttonCancel; // キャンセルボタン
SFRLabelControlPtr _labelDate; // 日時ラベル
SFRLabelControlPtr _labelHour; // 時間ラベル
SFRLabelControlPtr _labelMinute; // 分ラベル
SInt16 _fontHeight; // フォントの高さ
SFXDateConst _date; // 今日の日付
public:
DataInputWindow(SFXDateConstRef date) static_throws;
virtual ~DataInputWindow(Void);
virtual Void MakeData(SFXDateConstRef start,
SFXAnsiStringConstRef summary) = 0;
HANDLER_DECLARE_VOIDRENDER(OnRenderContent) // 描画ハンドラ
HANDLER_DECLARE_BOOLEVENT(OnKey) // キーハンドラ
HANDLER_DECLARE_VOIDCONTROL(OnOkButtonControl) // ボタンハンドラ
HANDLER_DECLARE_VOIDCONTROL(OnCancelButtonControl) // ボタンハンドラ
};
SFMTYPEDEFCLASS(CreateWindow)
class CreateWindow : public DataInputWindow {
SFMSEALCOPY(CreateWindow)
public:
CreateWindow(SFXDateConstRef date);
virtual Void MakeData(SFXDateConstRef start, SFXAnsiStringConstRef summary);
};
SFMTYPEDEFCLASS(ModifyWindow)
class ModifyWindow : public DataInputWindow {
SFMSEALCOPY(ModifyWindow)
private:
VCalendarFilePtr _vcal; // 修正するデータを保持
public:
ModifyWindow(SFXDateConstRef date, VCalendarFilePtr vcal);
virtual Void MakeData(SFXDateConstRef start, SFXAnsiStringConstRef summary);
};
コンストラクタ ( 抜粋 )
DataInputWindow::DataInputWindow(SFXDateConstRef date)
{
// フォントの高さを取得
_fontHeight = SFXGraphics::GetFontHeight(AEE_FONT_NORMAL);
SFXRectangleConst screenRect(GetContentWorld());
SFXRectangle rect(MENU_SIDE_MARGIN, MENU_TOP_MARGIN,
screenRect.GetRight() - MENU_SIDE_MARGIN, _fontHeight); //長方形
// ラベルの生成
_labelDate = ::new SFRLabelControl(this, rect, date.Format("YYYY年MM月DD日"));
rect.AddY(_fontHeight + MENU_SPACE);
rect.SetSize(MENU_BOX_WIDTH, _fontHeight + TEXTBOX_REVISING);
// 時間入力テキストコントロールの生成
_textHour = ::new SFRBrewTextControl(this, rect, "");
rect.AddX(MENU_BOX_WIDTH);
// ラベルの生成
_labelHour = ::new SFRLabelControl(this, rect, "時");
rect.AddX(rect.GetWidth());
// 分入力テキストコントロールの生成
_textMinute = ::new SFRBrewTextControl(this, rect, "");
rect.AddX(MENU_BOX_WIDTH);
// ラベルの生成
_labelMinute = ::new SFRLabelControl(this, rect, "分");
rect.SetX(MENU_SIDE_MARGIN);
rect.AddY(_fontHeight + MENU_SPACE + TEXTBOX_REVISING);
rect.SetSize(screenRect.GetRight() - 2 * MENU_SIDE_MARGIN,
screenRect.GetBottom() - 4 * MENU_SPACE
- 3 * _fontHeight - MENU_TOP_MARGIN);
// 内容入力テキストコントロールの生成
_textContent = ::new SFRBrewTextControl(this, rect, "");
rect.Set(MENU_SIDE_MARGIN, screenRect.GetBottom() - MENU_SPACE - _fontHeight,
MENU_BUTTON_WIDTH, _fontHeight);
// 決定ボタンの生成
_buttonOk = ::new SFRButtonControl(this, rect, "決定");
rect.AddX(MENU_SPACE + MENU_BUTTON_WIDTH);
// キャンセルボタンの生成
_buttonCancel = ::new SFRButtonControl(this, rect, "取消");
if (static_try()) {
// キーハンドラの登録
static_throw(RegisterHandler(SFEVT_KEY, AVK_SELECT,
HANDLER_AFTER, HANDLER_FUNCTION(SelectHandler)));
if (static_try()) {
if (_textHour != null && _textMinute != null && _textContent != null) {
// 最大文字数設定
_textHour->SetMaxSize(2);
_textMinute->SetMaxSize(2);
_textContent->SetMaxSize(255);
// フォーカスをあてる
_textHour->SetStatusFocus(true);
if (static_try()) {
if (_buttonOk != null) {
// ボタンハンドラの登録
static_throw(_buttonOk->RegisterHandler(SREVT_CONTROL,
HANDLER_BEFORE,HANDLER_FUNCTION(OnOkButtonControl)));
if (static_try()) {
if (_buttonCancel != null) {
// ボタンハンドラの登録
static_throw(_buttonCancel->RegisterHandler(
SREVT_CONTROL, HANDLER_BEFORE,
HANDLER_FUNCTION(OnCancelButtonControl)));
}
else {
static_throw(SFERR_NO_MEMORY);
}
}
}
else {
static_throw(SFERR_NO_MEMORY);
}
}
}
else {
static_throw(SFERR_NO_MEMORY);
}
}
}
}
ModifyWindow に関する追加処理
ModifyWindow::ModifyWindow(SFXDateConstRef date, VCalendarFilePtr vcal)
: DataInputWindow(date), // 親コンストラクタを呼び出す
_vcal(vcal) // 修正するデータ
{
SFXDate start = _vcal->GetStartDate();
// テキストコントロールの初期値に時間を設定
_textHour->SetText(SFXWideString::Format("%d", start.GetHour()));
// テキストコントロールの初期値に分を設定
_textMinute->SetText(SFXWideString::Format("%02d", start.GetMinute()));
// テキストコントロールの初期値に内容を設定
_textContent->SetText(_vcal->GetSummary());
return;
}
決定ボタンのハンドラ
HANDLER_IMPLEMENT_VOIDCONTROL(DataInputWindow, OnOkButtonControl, result, control)
{
SFXDate start(_date);
// テキストコントロールから文字列を取得して数値に変換
SInt16 hour = static_cast<SInt16>(_textHour->GetText().AsSInt32());
if (hour < 0 || hour >= 24) { // 範囲チェック
hour = 0;
}
start.SetHour(hour);
// テキストコントロールから文字列を取得して数値に変換
SInt16 minute = static_cast<SInt16>(_textMinute->GetText().AsSInt32());
if (minute < 0 || minute >= 60) { // 範囲チェック
minute = 0;
}
start.SetMinute(minute);
start.SetSecond(0); //秒は0とする(仕様)
// 内容入力テキストコントロールから文字列を取得
// ワイド文字列を Ansi 文字列に変換
SFXAnsiString summary(static_cast<SFXAnsiString>(
_textContent->GetText()));
// データ作成 (ウィンドウの種類によって異なる処理)
MakeData(start, summary);
// 後ろのウィンドウ (OneDayWindow) を取得
SFRResponderPtr oneDayWindow = GetNext();
// 自分自身と後ろのウィンドウの両方を閉じる
Invoke(SFXEvent(SREVT_RESPONDER_TERMINATE, SRP16_TERMINATE_INVOKE, true));
oneDayWindow->Invoke(SFXEvent(SREVT_RESPONDER_TERMINATE,
SRP16_TERMINATE_INVOKE, true));
return;
}
CreateWindow の MakeData 関数
Void CreateWindow::MakeData(SFXDateConstRef start, SFXAnsiStringConstRef summary)
{
VCalendarFilePtr vcal = ::new VCalendarFile("1.0", start, start, summary);
if (vcal != null) {
SyncScheduler::GetVCalCollection()->Append(vcal);
}
return;
}
ModifyWindow の MakeData 関数
Void ModifyWindow::MakeData(SFXDateConstRef start, SFXAnsiStringConstRef summary)
{
if (_vcal != null) {
_vcal->Set(start, start, start ,summary); //修正する
SyncScheduler::GetVCalCollection()->Update(_vcal);
}
return;
}
VCalCollection の Update 関数
Void VCalCollection::Update(VCalendarFilePtr vcalendar)
{
_list.Remove(_list.IndexOf(vcalendar));
Append(vcalendar);
vcalendar->SetFlag("m");
return;
}






















