* fix the animation timing, the notification start_time must be in millisec to avoid losing precision

* convert the animation duration to millisec once during settings parsing
* decrease the notification margin from 10.0 to 5.0, it looked way shifted on larger screens
* pass around instances on std::chrono instead of float, use float in the final stage when processing/operating-on the time (if needed)
* decrease the animation duration to 0.35 sec, looks more swishy!
This commit is contained in:
otavepto 2024-04-27 21:17:20 +03:00 committed by otavepto
parent 460c978100
commit 9f1e09b97a
5 changed files with 35 additions and 29 deletions

View File

@ -124,8 +124,9 @@ struct Overlay_Appearance {
float notification_g = 0.29f;
float notification_b = 0.48f;
float notification_a = 1.0f;
float notification_rounding = 0.0f;
float notification_animation = 0.0f;
float notification_rounding = 0.0f; // corners roundness for all notifications
uint32 notification_animation = 0; // sliding animation duration (millisec)
std::string ach_unlock_datetime_format = "%Y/%m/%d - %H:%M:%S";
float background_r = -1.0f;

View File

@ -257,7 +257,7 @@ static void load_overlay_appearance(class Settings *settings_client, class Setti
settings_client->overlay_appearance.notification_rounding = nnotification_rounding;
settings_server->overlay_appearance.notification_rounding = nnotification_rounding;
} else if (name.compare("Notification_Animation") == 0) {
float nnotification_animation = std::stof(value, NULL);
uint32 nnotification_animation = (uint32)(std::stof(value, NULL) * 1000.0f); // convert sec to milli
settings_client->overlay_appearance.notification_animation = nnotification_animation;
settings_server->overlay_appearance.notification_animation = nnotification_animation;
} else if (name.compare("Achievement_Unlock_Datetime_Format") == 0) {

View File

@ -69,7 +69,7 @@ struct Notification
int id{};
uint8 type{};
std::chrono::seconds start_time{};
std::chrono::milliseconds start_time{};
std::string message{};
std::pair<const Friend, friend_window_state>* frd{};
std::weak_ptr<uint64_t> icon{};
@ -187,8 +187,9 @@ class Steam_Overlay
// Double click on friend
void build_friend_window(Friend const& frd, friend_window_state &state);
// Notifications like achievements, chat and invitations
void set_next_notification_pos(float width, float height, float elapsed, const Notification &noti, struct NotificationsIndexes &idx);
float animate_factor(float elapsed);
void set_next_notification_pos(float width, float height, std::chrono::milliseconds elapsed, const Notification &noti, struct NotificationsIndexes &idx);
// factor controlling the amount of sliding during the animation, 0 means disabled
float animate_factor(std::chrono::milliseconds elapsed);
void build_notifications(int width, int height);
// invite a single friend
void invite_friend(uint64 friend_id, class Steam_Friends* steamFriends, class Steam_Matchmaking* steamMatchmaking);

View File

@ -604,7 +604,7 @@ bool Steam_Overlay::submit_notification(notification_type type, const std::strin
}
Notification notif{};
notif.start_time = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
notif.start_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
notif.id = id;
notif.type = (uint8)type;
notif.message = msg;
@ -834,7 +834,7 @@ void Steam_Overlay::build_friend_window(Friend const& frd, friend_window_state&
}
// set the position of the next notification
void Steam_Overlay::set_next_notification_pos(float width, float height, float elapsed, const Notification &noti, struct NotificationsIndexes &idx)
void Steam_Overlay::set_next_notification_pos(float width, float height, std::chrono::milliseconds elapsed, const Notification &noti, struct NotificationsIndexes &idx)
{
const float noti_width = width * Notification::width_percent;
@ -878,9 +878,9 @@ void Steam_Overlay::set_next_notification_pos(float width, float height, float e
// 0 on the y-axis is top, 0 on the x-axis is left
float x = 0.0f;
float y = 0.0f;
float anchor_margin = 10.0f;
float margin_y = 0.f;
float animate_size = 0.f;
float anchor_margin = 5.0f;
float margin_y = 0.0f;
float animate_size = 0.0f;
switch (pos) {
// top
@ -937,20 +937,23 @@ void Steam_Overlay::set_next_notification_pos(float width, float height, float e
ImGui::SetNextWindowBgAlpha(0.9f);
}
float Steam_Overlay::animate_factor(float elapsed)
float Steam_Overlay::animate_factor(std::chrono::milliseconds elapsed)
{
float factor = 0.0f;
float animation_duration = settings->overlay_appearance.notification_animation * 1000;
PRINT_DEBUG("ELAPSED %f", elapsed);
if (settings->overlay_appearance.notification_animation <= 0) return 0.0f; // no animation
if (animation_duration > 0) {
if (elapsed < animation_duration) {
factor = 1 - (elapsed / animation_duration);
PRINT_DEBUG("SHOW FACTOR %f", factor);
}
else if (elapsed > Notification::show_time.count() - animation_duration) {
factor = 1 - (Notification::show_time.count() - elapsed) / animation_duration;
PRINT_DEBUG("HIDE FACTOR %f", factor);
std::chrono::milliseconds animation_duration(settings->overlay_appearance.notification_animation);
// PRINT_DEBUG("ELAPSED %u/%u", (uint32)elapsed.count(), (uint32)animation_duration.count());
float factor = 0.0f;
if (elapsed < animation_duration) { // sliding in
factor = 1.0f - (static_cast<float>(elapsed.count()) / animation_duration.count());
// PRINT_DEBUG("SHOW FACTOR %f", factor);
} else {
// time between sliding in/out animation
auto steady_time = Notification::show_time - animation_duration;
if (elapsed > steady_time) {
factor = 1.0f - static_cast<float>((Notification::show_time - elapsed).count()) / animation_duration.count();
// PRINT_DEBUG("HIDE FACTOR %f", factor);
}
}
@ -970,7 +973,7 @@ void Steam_Overlay::build_notifications(int width, int height)
for (auto it = notifications.begin(); it != notifications.end(); ++it) {
auto elapsed_notif = now - it->start_time;
set_next_notification_pos(width, height, elapsed_notif.count(), *it, idx);
set_next_notification_pos(width, height, elapsed_notif, *it, idx);
if ( elapsed_notif < Notification::fade_in) { // still appearing (fading in)
float alpha = settings->overlay_appearance.notification_a * (elapsed_notif.count() / static_cast<float>(Notification::fade_in.count()));
@ -1033,11 +1036,12 @@ void Steam_Overlay::build_notifications(int width, int height)
case notification_type::invite: {
ImGui::TextWrapped("%s", it->message.c_str());
if (ImGui::Button(translationJoin[current_language]))
{
if (ImGui::Button(translationJoin[current_language])) {
it->frd->second.window_state |= window_state_join;
friend_actions_temp.push(it->frd->first);
it->start_time = std::chrono::seconds(0);
// when we click "accept game invite" from someone else, we want to remove this notification immediately since it's no longer relevant
// this assignment will make the notification elapsed time insanely large
it->start_time = std::chrono::milliseconds(0);
}
}
break;

View File

@ -47,11 +47,11 @@ Notification_G=0.15
Notification_B=0.18
Notification_A=1.0
# notification rounded corners
# notifications corners roundness
Notification_Rounding=10.0
# notification animation in seconds. Set to 0 to disable
Notification_Animation=0.5
Notification_Animation=0.35
# format for the achievement unlock date/time, limited to 79 characters
# if the output formatted string exceeded this limit, the builtin format will be used