⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clockpane.cpp

📁 一个基于BREW上的电子时钟程序,通过太阳历计算当前时间,并有闹铃和日志功能.
💻 CPP
字号:
//
//      ClockPane.cpp
//
//      Copyright (C) 2006 Sophia Cradle Incorporated

#include "ClockPane.hpp"
#include "pclock.hpp"

#define CLOCKPANE_UPDATE_INTERVAL			200		// 200 msec 枅偵夋柺傪峏怴
#define CLOCKPANE_UPDATE_INTERVAL2			1000	// ClockWindow 偑嵟慜柺偵昞帵偝傟偰偄側偄応崌偺峏怴昿搙
#define CLOCKPANE_HOURHAND_TO_MINUTEHAND	0.7		// (抁恓 / 昩恓)
#define CLOCKPANE_HAND_COLOR				153, 153, 153, 0	// 挿恓丒抁恓偺怓
#define CLOCKPANE_SECONDHAND_COLOR			204, 204, 204, 0	// 昩恓偺怓
#define CLOCKPANE_BACKGROUND_COLOR			255, 255, 255, 0	// 攚宨怓

ClockPane::ClockPane(SFRResponderPtr responder, SFXRectangleConstRef rect, SFXWideStringConstRef cityName, SFXDateDurationConstRef timeDifference) static_throws : SFRPane(responder, rect, SFXMargin(0, 0, 0, 0)), _timeDifference(timeDifference), _cityName(cityName), _simulation(false), _lastDate(0)
{
	if (static_try()) {
		static_throw(RegisterHandler(SREVT_RESPONDER_RENDER, SRP16_RENDER_CONTENT, HANDLER_BEFORE, HANDLER_FUNCTION(OnContent)));
	}
	if (static_try()) {
		static_throw(RegisterHandler(SFEVT_APP_SUSPEND, HANDLER_AFTER, HANDLER_FUNCTION(OnAppSuspend)));
	}
}

ClockPane::~ClockPane(Void)
{
	SFBShellSmp shell(SFBShell::GetInstance());

	shell->CancelTimer(null, this);
}

HANDLER_IMPLEMENT_VOIDRENDER(ClockPane, OnContent, graphics)
{
	SFXRectangle world(GetContentWorld());
	SInt16Const fontHeight(graphics->GetFontHeight());
	SFXRectangle clockRect, alarmRect, analogClockRect, rect;
	SFXDate localDate;
	SInt16 handCenterX, handCenterY, handX, handY;
	Float64 handLength, secondHandLength, fHour, fMinute, fSecond, theta;
	SFBShellSmp shell(SFBShell::GetInstance());
	SFXWideString alarmString;
	pclockPtr app(static_cast<pclockPtr>(SFRApplication::GetInstance()));

	if (!GetInheritEnable()) {
		return;
	}

	graphics->ClearRectangle(world, SFXRGBColor(CLOCKPANE_BACKGROUND_COLOR));

	alarmRect.SetSize(world.GetWidth(), fontHeight + 10);
	clockRect.SetSize(world.GetWidth(), world.GetHeight() - alarmRect.GetHeight());
	clockRect.SetOrigin(world.GetOrigin());
	alarmRect.SetOrigin(world.GetOrigin());
	alarmRect.SnapTop(clockRect.GetBottom());
	alarmRect.Inflate(2, 0, 2, 0);
	analogClockRect.SetSize(clockRect.GetHeight(), clockRect.GetHeight());
	analogClockRect.SnapLeftBottom(clockRect.GetLeftBottom());
	clockRect.Deflate(10, 10, 10, 10);

	localDate = (_simulation ? _simulationDate : SFXDate::CurrentUTCDate()) + _timeDifference;

	if (_lastDate != localDate) {
		// 傾僫儘僌帪寁傪昤夋
		handCenterX = analogClockRect.GetWidth() / 2 + analogClockRect.GetLeft();
		handCenterY = analogClockRect.GetHeight() / 2 + analogClockRect.GetTop();
		handLength = static_cast<Float64>(((analogClockRect.GetWidth() < analogClockRect.GetHeight()) ? analogClockRect.GetWidth() : analogClockRect.GetHeight()) / 2 - 2);
		secondHandLength = handLength * CLOCKPANE_HOURHAND_TO_MINUTEHAND;
		fHour = static_cast<Float64>(localDate.GetHour());
		fMinute = static_cast<Float64>(localDate.GetMinute());
		fSecond = static_cast<Float64>(localDate.GetSecond());
		// 抁恓偺嵗昗寁嶼
		theta = DegreeToRadian(- 90.0 + 30.0 * fHour + fMinute / 2.0 + fSecond / 120.0);
		handX = static_cast<SInt16>(secondHandLength * cos(theta)) + handCenterX;
		handY = static_cast<SInt16>(secondHandLength * sin(theta)) + handCenterY;
		_hourHand.Set(handCenterX, handCenterY, handX, handY);
		// 挿恓偺嵗昗寁嶼
		theta = DegreeToRadian(- 90.0 + 6.0 * fMinute + fSecond / 10.0);
		handX = static_cast<SInt16>(handLength * cos(theta)) + handCenterX;
		handY = static_cast<SInt16>(handLength * sin(theta)) + handCenterY;
		_minuteHand.Set(handCenterX, handCenterY, handX, handY);
		// 昩恓偺嵗昗寁嶼
		theta = DegreeToRadian(- 90.0 + 6.0 * fSecond);
		handX = static_cast<SInt16>(handLength * cos(theta)) + handCenterX;
		handY = static_cast<SInt16>(handLength * sin(theta)) + handCenterY;
		_secondHand.Set(handCenterX, handCenterY, handX, handY);
		_lastDate = localDate;
	}

	// 昤夋張棟
	graphics->DrawLine(_hourHand, SFXRGBColor(CLOCKPANE_HAND_COLOR));
	graphics->DrawLine(_minuteHand, SFXRGBColor(CLOCKPANE_HAND_COLOR));
	graphics->DrawLine(_secondHand, SFXRGBColor(CLOCKPANE_SECONDHAND_COLOR));
	
	graphics->DrawRectangle(alarmRect, SFXRGBColor(120, 120, 120, 0));
	alarmString = "ALARM - " + app->GetAlarmDate(_timeDifference);
	graphics->DrawText(alarmString, alarmRect, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE);

	rect = clockRect;
	graphics->DrawText(_cityName, rect, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_LEFT | IDF_ALIGN_TOP);
	
	rect.SetHeight(fontHeight * 4 + 15);
	rect.Offset(0, (clockRect.GetHeight() - rect.GetHeight()) / 2);
	graphics->DrawText(SFXWideString::Format("%hd擭", localDate.GetYear()), rect, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_RIGHT | IDF_ALIGN_TOP);
	rect.Offset(0, fontHeight + 5);
	graphics->DrawText(SFXWideString::Format("%02hd寧", localDate.GetMonth()), rect, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_RIGHT | IDF_ALIGN_TOP);
	rect.Offset(0, fontHeight + 5);
	graphics->DrawText(SFXWideString::Format("%02hd擔", localDate.GetDay()), rect, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_RIGHT | IDF_ALIGN_TOP);
	rect.Offset(0, fontHeight + 5);
	graphics->DrawText(SFXWideString::Format("%02hd:%02hd:%02hd", localDate.GetHour(), localDate.GetMinute(), localDate.GetSecond()), rect, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_RIGHT | IDF_ALIGN_TOP);

	if (!_simulation) {
		shell->SetTimer((GetDirector()->GetIndexForward() == 0) ? CLOCKPANE_UPDATE_INTERVAL : CLOCKPANE_UPDATE_INTERVAL2, UpdateSPP, this);
	}
}

// 帪寁偺峏怴傪堦帪揑偵抶傜偣傞
// mSec : 峏怴傪抶傜偣傞帪娫 (msec)
Void ClockPane::DelayUpdate(SInt32 mSec)
{
	SFBShellSmp shell(SFBShell::GetInstance());

	shell->CancelTimer(UpdateSPP, this);
	shell->SetTimer(mSec, UpdateSPP, this);
}

// 夋柺傪峏怴
Void ClockPane::UpdateSPP(VoidPtr /* data */)
{
	SFRApplication::GetInstance()->Invoke(SFXEvent(SREVT_RESPONDER_RENDER, SRP16_RENDER_INVOKE, true));
}

HANDLER_IMPLEMENT_VOIDSUSPEND(ClockPane, OnAppSuspend, reason, info)
{
	SFBShellSmp shell(SFBShell::GetInstance());

	unused(reason);
	unused(info);

	shell->CancelTimer(null, this);

	return;
}

// 僔儈儏儗乕僔儑儞昞帵偵愗傝懼偊傞
// utcDate : 僔儈儏儗乕僔儑儞偡傞擔晅 (UTC)
Void ClockPane::SetSimulation(SFXDateConstRef utcDate)
{
	SFBShellSmp shell(SFBShell::GetInstance());

	_simulationDate = utcDate;
	_simulation = true;
	shell->CancelTimer(null, this);
	InvalidateContent();
}

// 僔儈儏儗乕僔儑儞傪夝彍偡傞
Void ClockPane::CancelSimulation(Void)
{
	_simulation = false;
	InvalidateContent();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -