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

📄 astronomypane.cpp

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

#include "AstronomyPane.hpp"
#include "ClockWindow.hpp"
#include "SGRSoftkeyWindow.hpp"
#include "SGRSoftkeyToolbox.hpp"
#include "moon_res.h"
#include "pclock.hpp"

#define ASTRONOMYPANE_MOONAGERESFILE				"moon.bar"			// 寧偺奊偺儕僜乕僗僼傽僀儖
#define ASTRONOMYPANE_MOONAGE_WIDTH					60					// 寧偺奊偺暆
#define ASTRONOMYPANE_MOONAGE_HEIGHT				60					// 寧偺奊偺崅偝
#define ASTRONOMYPANE_MOONAGE_TRANSPARENCYCOLOR		255, 0, 255, 0		// 寧偺奊偺摟柧怓
#define ASTRONOMYPANE_UPDATE_DELAY					15					// 峏怴偺嵺惓帪偐傜抶傜偡帪娫 (sec)
#define ASTRONOMYPANE_BACKGROUND_COLOR				255, 255, 255, 0	// 攚宨怓

AstronomyPane::AstronomyPane(SFRResponderPtr responder, SFXRectangleConstRef rect, SFXDateDurationConstRef timeDifference, Float64 longitude, Float64 latitude, Float64 height) : SFRPane(responder, rect, SFXMargin(0, 0, 0, 0)), _moonAge(-1.0), _timeDifference(timeDifference), _longitude(longitude), _latitude(latitude), _height(height), _autoUpdate(true)
{
	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_RESUME, HANDLER_BEFORE, HANDLER_FUNCTION(OnAppResume)));
	}
	if (static_try()) {
		static_throw(RegisterHandler(SFEVT_APP_SUSPEND, HANDLER_AFTER, HANDLER_FUNCTION(OnAppSuspend)));
	}
}

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

	shell->CancelTimer(null, this);
}

SFXWideString AstronomyPane::GetMoonAgeString(Void) const
{
	SFXWideString str;
	SInt32 moonAge10;

	if (_moonAge >= 0.0) {
		moonAge10 = static_cast<SInt32>(floor(_moonAge * 10.0 + 0.5));
		str = SFXWideString::Format("寧楊 %2d.%d", moonAge10 / 10, moonAge10 % 10);
	}
	else {	// 寁嶼傪傑偩峴偭偰偄側偄
		str = "寧楊 --.-";
	}
	return str;
}

SFXWideString AstronomyPane::GetSunRiseString(Void) const
{
	SFXWideString str;
	AstronomicalMath::Date date;
	SFXDate localDate;

	if (_moonAge < 0.0) {
		// 傑偩寁嶼傪峴偭偰偄側偄
		str = "Sun Rise --:--";
	}
	else {
		if (_sun.GetRiseDateSize() == 0) {
			str = "Sun Rise --:--";
		}
		else {
			date = _sun.GetRiseDate(0);
			localDate = date.GetSFXDate() + _timeDifference + SFXDateDuration(30);
			str = SFXWideString::Format("Sun Rise %02hd:%02hd", localDate.GetHour(), localDate.GetMinute());
		}
	}
	return str;
}

SFXWideString AstronomyPane::GetSunSetString(Void) const
{
	SFXWideString str;
	AstronomicalMath::Date date;
	SFXDate localDate;

	if (_moonAge < 0.0) {
		// 傑偩寁嶼傪峴偭偰偄側偄
		str = "Sun Set  --:--";
	}
	else {
		if (_sun.GetSetDateSize() == 0) {
			str = "Sun Set  --:--";
		}
		else {
			date = _sun.GetSetDate(0);
			localDate = date.GetSFXDate() + _timeDifference + SFXDateDuration(30);
			str = SFXWideString::Format("Sun Set  %02hd:%02hd", localDate.GetHour(), localDate.GetMinute());
		}
	}
	return str;
}

SFXWideString AstronomyPane::GetMoonRiseString(Void) const
{
	SFXWideString str;
	AstronomicalMath::Date date;
	SFXDate localDate;

	if (_moonAge < 0.0) {
		// 傑偩寁嶼傪峴偭偰偄側偄
		str = "Moon Rise --:--";
	}
	else {
		if (_moon.GetRiseDateSize() == 0) {
			str = "Moon Rise --:--";
		}
		else {
			date = _moon.GetRiseDate(0);
			localDate = date.GetSFXDate() + _timeDifference + SFXDateDuration(30);
			str = SFXWideString::Format("Moon Rise %02hd:%02hd", localDate.GetHour(), localDate.GetMinute());
		}
	}
	return str;
}

SFXWideString AstronomyPane::GetMoonSetString(Void) const
{
	SFXWideString str;
	AstronomicalMath::Date date;
	SFXDate localDate;

	if (_moonAge < 0.0) {
		// 傑偩寁嶼傪峴偭偰偄側偄
		str = "Moon Set  --:--";
	}
	else {
		if (_moon.GetSetDateSize() == 0) {
			str = "Moon Set  --:--";
		}
		else {
			date = _moon.GetSetDate(0);
			localDate = date.GetSFXDate() + _timeDifference + SFXDateDuration(30);
			str = SFXWideString::Format("Moon Set  %02hd:%02hd", localDate.GetHour(), localDate.GetMinute());
		}
	}
	return str;
}

HANDLER_IMPLEMENT_VOIDRENDER(AstronomyPane, OnContent, graphics)
{
	SFXRectangle world(GetContentWorld());
	SInt16Const fontHeight(graphics->GetFontHeight());
	SFXRectangle moonAgeWindow;
	SFXRectangle moonAgePictureRect;
	SFXRectangle sunRiseWindow, sunSetWindow;
	SFXRectangle moonRiseWindow, moonSetWindow;
	SInt32 moonAgeInt(0);
	SFBShellSmp shell(SFBShell::GetInstance());
	SFBBitmapSmp bitmap, resBitmap;
	SFCError error(SFERR_NO_ERROR);
	SFXRGBColor rgb(ASTRONOMYPANE_MOONAGE_TRANSPARENCYCOLOR);
	RGBVAL rgbVal(0);
	NativeColor native(0);

	if (!GetInheritEnable()) {
		return;
	}
	
	graphics->ClearRectangle(world, SFXRGBColor(ASTRONOMYPANE_BACKGROUND_COLOR));
	world.Deflate(10, 10, 10, 10);

	// 寧楊傪昞帵偡傞
	if (_moonAge >= 0.0) {
		moonAgeInt = static_cast<SInt32>(floor(_moonAge + 0.5));
		if (moonAgeInt > 29) {
			moonAgeInt = 0;
		}
	}
	if (moonAgeInt > 0) {
		// 寧偺奊傪昞帵
		bitmap = SFXGraphics::CreateBitmap(SFXSize(ASTRONOMYPANE_MOONAGE_WIDTH, ASTRONOMYPANE_MOONAGE_HEIGHT));
		if (bitmap != null) {
			resBitmap = shell->LoadResBitmap(ASTRONOMYPANE_MOONAGERESFILE, MOONAGE_01 + (moonAgeInt - 1));
			if (resBitmap != null) {
				error = bitmap->BltIn(0, 0, ASTRONOMYPANE_MOONAGE_WIDTH, ASTRONOMYPANE_MOONAGE_HEIGHT, resBitmap, 0, 0, AEE_RO_COPY);
				if (error == SFERR_NO_ERROR) {
					// 摟柧怓偺愝掕
					rgbVal = rgb.ToRGBVAL();
					native = bitmap->RGBToNative(rgbVal);
					bitmap->SetTransparencyColor(native);

					// 昞帵埵抲傪寁嶼
					moonAgePictureRect.SetSize(ASTRONOMYPANE_MOONAGE_WIDTH, ASTRONOMYPANE_MOONAGE_HEIGHT);
					moonAgePictureRect.SetOrigin(world.GetX() + 50, world.GetY());
					graphics->DrawBitmap(bitmap, moonAgePictureRect, AEE_RO_TRANSPARENT);
				}
			}
		}
	}
	moonAgeWindow.SetSize(100, fontHeight);
	moonAgeWindow.SetOrigin(world.GetX() + 8, world.GetY() + (ASTRONOMYPANE_MOONAGE_HEIGHT - fontHeight) / 2 - 6);
	graphics->DrawText(GetMoonAgeString(), moonAgeWindow, SFXRGBColor(0, 0, 0, 0));

	// 懢梲偺弌杤帪崗傪昞帵
	sunSetWindow.SetSize(world.GetWidth(), fontHeight);
	sunSetWindow.SnapRightBottom(world.GetRightBottom());
	graphics->DrawText(GetSunSetString(), sunSetWindow, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_RIGHT);
	sunRiseWindow.SetSize(world.GetWidth(), fontHeight);
	sunRiseWindow.SnapLeftBottom(sunSetWindow.GetLeftTop());
	sunRiseWindow.Offset(0, -2);
	graphics->DrawText(GetSunRiseString(), sunRiseWindow, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_RIGHT);

	// 寧偺弌杤帪崗傪昞帵
	moonSetWindow.SetSize(world.GetWidth(), fontHeight);
	moonSetWindow.SnapLeft(world.GetLeft());
	moonSetWindow.SnapBottom(sunRiseWindow.GetTop());
	moonSetWindow.Offset(0, -4);
	graphics->DrawText(GetMoonSetString(), moonSetWindow, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_LEFT);
	moonRiseWindow.SetSize(world.GetWidth(), fontHeight);
	moonRiseWindow.SnapLeftBottom(moonSetWindow.GetLeftTop());
	graphics->DrawText(GetMoonRiseString(), moonRiseWindow, SFXRGBColor(0, 0, 0, 0), IDF_ALIGN_LEFT);
}

// 揤懱忣曬傪峏怴偡傞 (撪晹屇傃弌偟梡)
Void AstronomyPane::UpdateInformationInner(Void)
{
	SFXRectangle display(SGRSoftkeyToolbox::GetWindowPosition());
	SFXRectangle rect;
	SFXGraphicsPtr graphics(SFXGraphics::GetInstance());
	SFBShellSmp shell(SFBShell::GetInstance());
	SGRSoftkeyWindowPtr softkey(null);

	// 寁嶼拞偱偁傞巪傪昞帵
	rect.SetSize(display.GetWidth() - 20, graphics->GetFontHeight() * 2);
	rect.SnapLeftTop(display.GetLeftTop());
	rect.Offset((display.GetWidth() - rect.GetWidth()) / 2, (display.GetHeight() - rect.GetHeight()) / 2);

	_dialog = ::new SFRMessageDialog(rect, "寁嶼拞...", "");
	if (!_dialog) {
		static_throw(SFERR_NO_MEMORY);
	}
	else {
		static_throw(*_dialog);
	}
	if (!static_try()) {
		::delete _dialog;
		_dialog = null;
	}
	if (static_try()) {
		static_throw(_dialog->RegisterHandler(SFEVT_KEY, HANDLER_BEFORE, HANDLER_FUNCTION(OnNoButtonDialogKey)));
	}
	if (static_try()) {
		SGRSoftkeyWindow::Initialize(_dialog);
		static_throw(_dialog->RegisterHandler(static_cast<SFCEventEnum>(SGRSoftkeyWindow::USEREVT_SOFTKEY), HANDLER_BEFORE, HANDLER_FUNCTION(OnNoButtonDialogSoftkey)));
	}
	softkey = SGRSoftkeyWindow::GetInstance();
	if (softkey && static_try()) {
		_dialog->SetReference(softkey->Bind(_dialog));
	}
	SFRApplication::GetInstance()->Invoke(SFXEvent(SREVT_RESPONDER_RENDER, SRP16_RENDER_INVOKE, true));

	// 幚嵺偺寁嶼偼 100 ms 屻偵奐巒偡傞
	shell->CancelTimer(null, this);
	shell->SetTimer(100, UpdateInformationTimerSPP, this);
}

// 尰嵼偺帪崗傪巊梡偟偰丄揤懱偺忣曬傪峏怴偡傞
Void AstronomyPane::UpdateInformation(Void)
{
	_gmtDate = SFXDate::CurrentUTCDate();
	_autoUpdate = true;
	UpdateInformationInner();
}

// 巜掕偝傟偨帪崗偺揤懱忣曬傪寁嶼偡傞
// utcDate : UTC 偱偺帪崗
Void AstronomyPane::UpdateInformation(SFXDateConstRef utcDate)
{
	_gmtDate = utcDate;
	_autoUpdate = false;
	UpdateInformationInner();
}

Void AstronomyPane::UpdateInformationTimerSPP(VoidPtr data)
{
	AstronomyPanePtr p(static_cast<AstronomyPanePtr>(data));

	p->Compute();
}

// 揤懱忣曬傪寁嶼偡傞
Void AstronomyPane::Compute(Void)
{
	SFXDateConst localDate(_gmtDate + _timeDifference);
	SFXDateConst date0(localDate.GetYear(), localDate.GetMonth(), localDate.GetDay(), 0, 0, 0);
	AstronomicalMath::DateConst initialDate(date0 - _timeDifference);
	SFXDate nextUpdate, currentDate;
	SFXDateDuration sec;
	SFBShellSmp shell(SFBShell::GetInstance());
	pclockPtr app(static_cast<pclockPtr>(SFRApplication::GetInstance()));

	_moonAge = AstronomicalMath::GetMoonAge(AstronomicalMath::Date(_gmtDate));
	_sun.Set(initialDate, _longitude, _latitude, _height);
	_sun.Compute();
	_moon.Set(initialDate, _longitude, _latitude, _height);
	_moon.Compute();
	
	if (_dialog) {
		if (_dialog->GetIndexForward() == 0) {
			SGRSoftkeyWindow::Terminate(_dialog);
			_dialog->DialogHandler();
			_dialog = null;
		}
		else {
			app->SetRemoveDialog(_dialog);
			_dialog = null;
		}
	}
	SFRApplication::GetInstance()->Invoke(SFXEvent(SREVT_RESPONDER_RENDER, SRP16_RENDER_INVOKE, true));

	if (_autoUpdate) {
		currentDate = SFXDate::CurrentDate();
		nextUpdate.Set(currentDate.GetYear(), currentDate.GetMonth(), currentDate.GetDay(), currentDate.GetHour(), 0, 0);
		nextUpdate.AddHour(1);
		sec = nextUpdate - currentDate;
		shell->SetTimer((sec.ToSInt32() + ASTRONOMYPANE_UPDATE_DELAY) * 1000, HourlyUpdate, this);
	}
}

// 1 帪娫枅偵楋傪峏怴偡傞
Void AstronomyPane::HourlyUpdate(VoidPtr data)
{
	AstronomyPanePtr p(static_cast<AstronomyPanePtr>(data));
	p->UpdateInformation();
}

HANDLER_IMPLEMENT_VOIDRESUME(AstronomyPane, OnAppResume, environment)
{
	unused(environment);

	if (_autoUpdate) {
		UpdateInformation();
	}

	return;
}

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

	unused(reason);
	unused(info);

	shell->CancelTimer(null, this);
	return;
}

// 儃僞儞側偟僟僀傾儘僌偺僀儀儞僩僴儞僪儔
// 僉乕 僀儀儞僩偼栤摎柍梡偱幪偰傞
HANDLER_IMPLEMENT_BOOLEVENT(AstronomyPane, OnNoButtonDialogKey, event)
{
	unused(event);
	return true;
}

// 僜僼僩 僉乕 僀儀儞僩偼栤摎柍梡偱幪偰傞
HANDLER_IMPLEMENT_VOIDEVENT(AstronomyPane, OnNoButtonDialogSoftkey, event)
{
	unused(event);
}

⌨️ 快捷键说明

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