Refactor alarm system and replace notification method

The old OpenVR overlays did not function for unknown reasons, and it was
not possible to get them to work.

With this a white overlay with ALARM ACTIVATED will be shown for 3 seconds.
It's not pretty, but it effectively communicates that an alarm has been
activated.

This fixes
https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/issues/417
This commit is contained in:
Vasily
2020-06-05 20:52:13 +02:00
committed by username223
parent 8c2af7477c
commit 4757756d32
16 changed files with 531 additions and 457 deletions
@@ -12,13 +12,6 @@ namespace advsettings
{
void UtilitiesTabController::initStage1()
{
auto qAlarmHour
= settings::getSetting( settings::IntSetting::UTILITY_alarmHour );
auto qAlarmMinute
= settings::getSetting( settings::IntSetting::UTILITY_alarmMinute );
m_alarmTime = QTime( qAlarmHour, qAlarmMinute );
m_utilitiesSettingsUpdateCounter
= utils::adjustUpdateRate( k_utilitiesSettingsUpdateCounter );
}
@@ -202,53 +195,11 @@ void UtilitiesTabController::sendKeyboardThree()
sendStringAsInput( commands );
}
bool UtilitiesTabController::alarmEnabled() const
{
return settings::getSetting( settings::BoolSetting::UTILITY_alarmEnabled );
}
bool UtilitiesTabController::alarmIsModal() const
{
return settings::getSetting( settings::BoolSetting::UTILITY_alarmIsModal );
}
bool UtilitiesTabController::vrcDebug() const
{
return settings::getSetting( settings::BoolSetting::UTILITY_vrcDebug );
}
int UtilitiesTabController::alarmTimeHour() const
{
return m_alarmTime.hour();
}
int UtilitiesTabController::alarmTimeMinute() const
{
return m_alarmTime.minute();
}
void UtilitiesTabController::setAlarmEnabled( bool enabled, bool notify )
{
settings::setSetting( settings::BoolSetting::UTILITY_alarmEnabled,
enabled );
m_alarmLastCheckTime = QTime();
if ( notify )
{
emit alarmEnabledChanged( enabled );
}
}
void UtilitiesTabController::setAlarmIsModal( bool modal, bool notify )
{
settings::setSetting( settings::BoolSetting::UTILITY_alarmIsModal, modal );
if ( notify )
{
emit alarmIsModalChanged( modal );
}
}
void UtilitiesTabController::setVrcDebug( bool value, bool notify )
{
settings::setSetting( settings::BoolSetting::UTILITY_vrcDebug, value );
@@ -258,116 +209,6 @@ void UtilitiesTabController::setVrcDebug( bool value, bool notify )
}
}
void UtilitiesTabController::setAlarmTimeHour( int hour, bool notify )
{
if ( m_alarmTime.hour() == hour )
{
return;
}
if ( m_alarmTime.isValid() )
{
m_alarmTime = QTime( hour, m_alarmTime.minute() );
}
else
{
m_alarmTime = QTime( hour, 0 );
}
settings::setSetting( settings::IntSetting::UTILITY_alarmHour,
m_alarmTime.hour() );
settings::setSetting( settings::IntSetting::UTILITY_alarmMinute,
m_alarmTime.minute() );
m_alarmLastCheckTime = QTime();
if ( notify )
{
emit alarmTimeHourChanged( hour );
}
}
void UtilitiesTabController::setAlarmTimeMinute( int min, bool notify )
{
if ( m_alarmTime.minute() != min )
{
if ( m_alarmTime.isValid() )
{
m_alarmTime = QTime( m_alarmTime.hour(), min );
}
else
{
m_alarmTime = QTime( 0, min );
}
settings::setSetting( settings::IntSetting::UTILITY_alarmHour,
m_alarmTime.hour() );
settings::setSetting( settings::IntSetting::UTILITY_alarmMinute,
m_alarmTime.minute() );
m_alarmLastCheckTime = QTime();
if ( notify )
{
emit alarmTimeMinuteChanged( min );
}
}
}
void UtilitiesTabController::setAlarmTimeToCurrentTime()
{
auto now = QTime::currentTime();
setAlarmTimeHour( now.hour() );
setAlarmTimeMinute( now.minute() );
}
void UtilitiesTabController::modAlarmTimeHour( int value, bool notify )
{
auto h = m_alarmTime.hour();
m_alarmTime = m_alarmTime.addSecs( value * 60 * 60 );
settings::setSetting( settings::IntSetting::UTILITY_alarmHour,
m_alarmTime.hour() );
settings::setSetting( settings::IntSetting::UTILITY_alarmMinute,
m_alarmTime.minute() );
if ( h != m_alarmTime.hour() )
{
m_alarmLastCheckTime = QTime();
if ( notify )
{
emit alarmTimeHourChanged( m_alarmTime.hour() );
}
}
}
void UtilitiesTabController::modAlarmTimeMinute( int value, bool notify )
{
auto h = m_alarmTime.hour();
auto m = m_alarmTime.minute();
m_alarmTime = m_alarmTime.addSecs( value * 60 );
settings::setSetting( settings::IntSetting::UTILITY_alarmHour,
m_alarmTime.hour() );
settings::setSetting( settings::IntSetting::UTILITY_alarmMinute,
m_alarmTime.minute() );
if ( m != m_alarmTime.minute() || h != m_alarmTime.hour() )
{
m_alarmLastCheckTime = QTime();
if ( notify )
{
if ( h != m_alarmTime.hour() )
{
emit alarmTimeHourChanged( m_alarmTime.hour() );
}
if ( m != m_alarmTime.minute() )
{
emit alarmTimeMinuteChanged( m_alarmTime.minute() );
}
}
}
}
QString getBatteryIconPath( int batteryState )
{
constexpr auto batteryPrefix = "/res/img/battery/battery_";
@@ -431,136 +272,6 @@ void UtilitiesTabController::eventLoopTick()
{
if ( settingsUpdateCounter >= m_utilitiesSettingsUpdateCounter )
{
if ( alarmEnabled() && m_alarmTime.isValid() )
{
auto now = QTime::currentTime();
if ( m_alarmLastCheckTime.isValid()
&& m_alarmLastCheckTime <= m_alarmTime && m_alarmTime <= now )
{
setAlarmEnabled( false );
char alarmMessageBuffer[1024];
std::snprintf( alarmMessageBuffer,
1024,
"The alarm at %02i:%02i went off.",
alarmTimeHour(),
alarmTimeMinute() );
if ( alarmIsModal() )
{
std::thread messageThread(
[]( UtilitiesTabController* parent,
std::string message ) {
auto res = vr::VROverlay()->ShowMessageOverlay(
message.c_str(),
"Alarm Clock",
"Ok",
"+15 min" );
if ( res
== vr::VRMessageOverlayResponse_ButtonPress_1 )
{
parent->setAlarmTimeToCurrentTime();
parent->modAlarmTimeMinute( 15 );
parent->setAlarmEnabled( true );
}
else if (
res >= vr::
VRMessageOverlayResponse_CouldntFindSystemOverlay )
{
static const char* errorMessages[]
= { "CouldntFindSystemOverlay",
"CouldntFindOrCreateClientOverlay",
"ApplicationQuit" };
int errorCode
= res
- vr::
VRMessageOverlayResponse_CouldntFindSystemOverlay;
if ( res < 3 )
{
LOG( ERROR )
<< "Could not create Alarm Overlay: "
<< errorMessages[errorCode];
}
else
{
LOG( ERROR ) << "Could not create Alarm "
"Overlay: Unknown Error";
}
}
},
this,
std::string( alarmMessageBuffer ) );
messageThread.detach();
}
else
{
vr::VRNotificationId notificationId;
vr::EVRInitError eError;
vr::IVRNotifications* vrnotification
= static_cast<vr::IVRNotifications*>(
vr::VR_GetGenericInterface(
vr::IVRNotifications_Version, &eError ) );
if ( eError != vr::VRInitError_None )
{
LOG( ERROR )
<< "Error while getting IVRNotifications interface"
<< vr::VR_GetVRInitErrorAsEnglishDescription(
eError );
vrnotification = nullptr;
}
else
{
vr::NotificationBitmap_t* messageIconPtr = nullptr;
/*
// Can i even create this object on the stack, who takes
ownership? vr::NotificationBitmap_t messageIcon;
// First get image width and height
vr::VROverlay()->GetOverlayImageData(parent->overlayThumbnailHandle(),
nullptr, 0, (uint32_t*)&messageIcon.m_nWidth,
(uint32_t*)&messageIcon.m_nHeight);
messageIcon.m_nBytesPerPixel = 4;
unsigned bufferSize =
messageIcon.m_nWidth*messageIcon.m_nHeight*messageIcon.m_nBytesPerPixel;
// Can I delete this buffer after this section? Who
takes ownership? std::unique_ptr<char> imageBuffer;
imageBuffer.reset(new char[bufferSize]);
messageIcon.m_pImageData = imageBuffer.get();
// Get image data
auto iconError =
vr::VROverlay()->GetOverlayImageData(parent->overlayThumbnailHandle(),
messageIcon.m_pImageData, bufferSize,
(uint32_t*)&messageIcon.m_nWidth,
(uint32_t*)&messageIcon.m_nHeight); if (iconError !=
vr::VROverlayError_None) { LOG(ERROR) << "Error while
getting message overlay icon: " <<
vr::VROverlay()->GetOverlayErrorNameFromEnum(iconError);
} else {
messageIconPtr = &messageIcon;
}
*/
auto nError = vrnotification->CreateNotification(
m_parent->overlayHandle(),
666,
vr::EVRNotificationType_Transient,
alarmMessageBuffer,
vr::EVRNotificationStyle_Application,
messageIconPtr,
&notificationId );
if ( nError != vr::VRNotificationError_OK )
{
LOG( ERROR )
<< "Error while creating notification: "
<< nError;
vrnotification = nullptr;
}
}
}
}
m_alarmLastCheckTime = now;
}
// attach battery overlay to all tracked devices that aren't a
// controller or hmd
for ( vr::TrackedDeviceIndex_t i = 0; i < vr::k_unMaxTrackedDeviceCount;