mirror of
https://github.com/Detanup01/gbe_fork.git
synced 2024-11-23 19:25:35 +08:00
* revert the changes to the notifications heights + calculate all notifications heights dynamically
* added a new button to the overlay `"Test achievement"` which triggeres a test achievement * added a new overlay appearance option `Achievement_Unlock_Datetime_Format` which allows changing the date/time format of the unlocked achievements * removed the condition which disabled the overlay sounds when it is shown
This commit is contained in:
parent
bda4fbca2c
commit
21cce304e8
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,3 +1,16 @@
|
|||||||
|
## 2024/4/25
|
||||||
|
|
||||||
|
* **[schmurger]** improved achievement notification:
|
||||||
|
- added new overlay appearance option `Notification_Rounding` which allows increasing the roundness of the notifications corners
|
||||||
|
- the overlay ini file now contains color scheme similar to the one used in steam for the notification background
|
||||||
|
* added a new button to the overlay `"Test achievement"` which triggeres a test achievement, suggested by **[Kirius88]**
|
||||||
|
note that the icon for this test achievement is selected randomly from the current list of achievements
|
||||||
|
* added a new overlay appearance option `Achievement_Unlock_Datetime_Format` which allows changing the date/time format of the unlocked achievements, suggested by **[Clompress]**
|
||||||
|
* removed the condition which disabled the overlay sounds when it is shown, suggested by **[Vlxst]**
|
||||||
|
* calculate all notifications heights dynamically
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2024/4/23
|
## 2024/4/23
|
||||||
|
|
||||||
* fixed local saving + ignore the global settings folder entirely when using the local save option for a full portable behavior
|
* fixed local saving + ignore the global settings folder entirely when using the local save option for a full portable behavior
|
||||||
|
@ -124,7 +124,9 @@ struct Overlay_Appearance {
|
|||||||
float notification_g = 0.29f;
|
float notification_g = 0.29f;
|
||||||
float notification_b = 0.48f;
|
float notification_b = 0.48f;
|
||||||
float notification_a = 1.0f;
|
float notification_a = 1.0f;
|
||||||
float notification_rounding = 0.f;
|
float notification_rounding = 0.0f;
|
||||||
|
std::string ach_unlock_datetime_format = "%Y/%m/%d - %H:%M:%S";
|
||||||
|
|
||||||
float background_r = -1.0f;
|
float background_r = -1.0f;
|
||||||
float background_g = -1.0f;
|
float background_g = -1.0f;
|
||||||
float background_b = -1.0f;
|
float background_b = -1.0f;
|
||||||
|
@ -256,6 +256,9 @@ static void load_overlay_appearance(class Settings *settings_client, class Setti
|
|||||||
float nnotification_rounding = std::stof(value, NULL);
|
float nnotification_rounding = std::stof(value, NULL);
|
||||||
settings_client->overlay_appearance.notification_rounding = nnotification_rounding;
|
settings_client->overlay_appearance.notification_rounding = nnotification_rounding;
|
||||||
settings_server->overlay_appearance.notification_rounding = nnotification_rounding;
|
settings_server->overlay_appearance.notification_rounding = nnotification_rounding;
|
||||||
|
} else if (name.compare("Achievement_Unlock_Datetime_Format") == 0) {
|
||||||
|
settings_client->overlay_appearance.ach_unlock_datetime_format = value;
|
||||||
|
settings_server->overlay_appearance.ach_unlock_datetime_format = value;
|
||||||
} else if (name.compare("Background_R") == 0) {
|
} else if (name.compare("Background_R") == 0) {
|
||||||
float nbackground_r = std::stof(value, NULL);
|
float nbackground_r = std::stof(value, NULL);
|
||||||
settings_client->overlay_appearance.background_r = nbackground_r;
|
settings_client->overlay_appearance.background_r = nbackground_r;
|
||||||
|
@ -24,6 +24,7 @@ enum window_state
|
|||||||
window_state_rich_invite = 1<<4,
|
window_state_rich_invite = 1<<4,
|
||||||
window_state_send_message = 1<<5,
|
window_state_send_message = 1<<5,
|
||||||
window_state_need_attention = 1<<6,
|
window_state_need_attention = 1<<6,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct friend_window_state
|
struct friend_window_state
|
||||||
@ -50,46 +51,46 @@ struct Friend_Less
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum notification_type
|
enum class notification_type
|
||||||
{
|
{
|
||||||
notification_type_message = 0,
|
message = 0,
|
||||||
notification_type_invite,
|
invite,
|
||||||
notification_type_achievement,
|
achievement,
|
||||||
notification_type_auto_accept_invite,
|
auto_accept_invite,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Notification
|
struct Notification
|
||||||
{
|
{
|
||||||
static constexpr float width_percent = 0.25f; // percentage from total width
|
static constexpr float width_percent = 0.25f; // percentage from total width
|
||||||
static constexpr float height = 6.5f;
|
|
||||||
static constexpr std::chrono::milliseconds fade_in = std::chrono::milliseconds(2000);
|
static constexpr std::chrono::milliseconds fade_in = std::chrono::milliseconds(2000);
|
||||||
static constexpr std::chrono::milliseconds fade_out = std::chrono::milliseconds(2000);
|
static constexpr std::chrono::milliseconds fade_out = std::chrono::milliseconds(2000);
|
||||||
static constexpr std::chrono::milliseconds show_time = std::chrono::milliseconds(6000) + fade_in + fade_out;
|
static constexpr std::chrono::milliseconds show_time = std::chrono::milliseconds(6000) + fade_in + fade_out;
|
||||||
static constexpr std::chrono::milliseconds fade_out_start = show_time - fade_out;
|
static constexpr std::chrono::milliseconds fade_out_start = show_time - fade_out;
|
||||||
|
|
||||||
int id;
|
int id{};
|
||||||
uint8 type;
|
uint8 type{};
|
||||||
std::chrono::seconds start_time;
|
std::chrono::seconds start_time{};
|
||||||
std::string message;
|
std::string message{};
|
||||||
std::pair<const Friend, friend_window_state>* frd;
|
std::pair<const Friend, friend_window_state>* frd{};
|
||||||
std::weak_ptr<uint64_t> icon;
|
std::weak_ptr<uint64_t> icon{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Overlay_Achievement
|
struct Overlay_Achievement
|
||||||
{
|
{
|
||||||
std::string name;
|
|
||||||
std::string title;
|
|
||||||
std::string description;
|
|
||||||
std::string icon_name;
|
|
||||||
std::string icon_gray_name;
|
|
||||||
bool hidden;
|
|
||||||
bool achieved;
|
|
||||||
uint32 unlock_time;
|
|
||||||
std::weak_ptr<uint64_t> icon;
|
|
||||||
std::weak_ptr<uint64_t> icon_gray;
|
|
||||||
|
|
||||||
// avoids spam loading on failure
|
// avoids spam loading on failure
|
||||||
constexpr const static int ICON_LOAD_MAX_TRIALS = 3;
|
constexpr const static int ICON_LOAD_MAX_TRIALS = 3;
|
||||||
|
|
||||||
|
std::string name{};
|
||||||
|
std::string title{};
|
||||||
|
std::string description{};
|
||||||
|
std::string icon_name{};
|
||||||
|
std::string icon_gray_name{};
|
||||||
|
bool hidden{};
|
||||||
|
bool achieved{};
|
||||||
|
uint32 unlock_time{};
|
||||||
|
std::weak_ptr<uint64_t> icon{};
|
||||||
|
std::weak_ptr<uint64_t> icon_gray{};
|
||||||
|
|
||||||
uint8_t icon_load_trials = ICON_LOAD_MAX_TRIALS;
|
uint8_t icon_load_trials = ICON_LOAD_MAX_TRIALS;
|
||||||
uint8_t icon_gray_load_trials = ICON_LOAD_MAX_TRIALS;
|
uint8_t icon_gray_load_trials = ICON_LOAD_MAX_TRIALS;
|
||||||
};
|
};
|
||||||
@ -127,6 +128,7 @@ class Steam_Overlay
|
|||||||
bool show_overlay = false;
|
bool show_overlay = false;
|
||||||
bool show_achievements = false;
|
bool show_achievements = false;
|
||||||
bool show_settings = false;
|
bool show_settings = false;
|
||||||
|
bool show_test_ach = false;
|
||||||
|
|
||||||
// warn when using local save
|
// warn when using local save
|
||||||
bool warn_local_save = false;
|
bool warn_local_save = false;
|
||||||
@ -185,7 +187,7 @@ class Steam_Overlay
|
|||||||
// Double click on friend
|
// Double click on friend
|
||||||
void build_friend_window(Friend const& frd, friend_window_state &state);
|
void build_friend_window(Friend const& frd, friend_window_state &state);
|
||||||
// Notifications like achievements, chat and invitations
|
// Notifications like achievements, chat and invitations
|
||||||
void set_next_notification_pos(float width, float height, float font_size, notification_type type, struct NotificationsIndexes &idx);
|
void set_next_notification_pos(float width, float height, const Notification ¬i, struct NotificationsIndexes &idx);
|
||||||
void build_notifications(int width, int height);
|
void build_notifications(int width, int height);
|
||||||
// invite a single friend
|
// invite a single friend
|
||||||
void invite_friend(uint64 friend_id, class Steam_Friends* steamFriends, class Steam_Matchmaking* steamMatchmaking);
|
void invite_friend(uint64 friend_id, class Steam_Friends* steamFriends, class Steam_Matchmaking* steamMatchmaking);
|
||||||
@ -205,9 +207,8 @@ class Steam_Overlay
|
|||||||
void obscure_game_input(bool state);
|
void obscure_game_input(bool state);
|
||||||
|
|
||||||
void add_auto_accept_invite_notification();
|
void add_auto_accept_invite_notification();
|
||||||
|
|
||||||
void add_invite_notification(std::pair<const Friend, friend_window_state> &wnd_state);
|
void add_invite_notification(std::pair<const Friend, friend_window_state> &wnd_state);
|
||||||
|
void post_achievement_notification(Overlay_Achievement &ach);
|
||||||
void add_chat_message_notification(std::string const& message);
|
void add_chat_message_notification(std::string const& message);
|
||||||
|
|
||||||
bool open_overlay_hook(bool toggle);
|
bool open_overlay_hook(bool toggle);
|
||||||
|
@ -188,6 +188,98 @@ const char translationCopyId[TRANSLATION_NUMBER_OF_LANGUAGES][TRANSLATION_BUFFER
|
|||||||
u8"Copy ID",
|
u8"Copy ID",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char translationTestAchievement[TRANSLATION_NUMBER_OF_LANGUAGES][TRANSLATION_BUFFER_SIZE] = {
|
||||||
|
// 0 - English
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 1 - Arabic
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 2 - Bulgarian
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 3 - Simplified Chinese
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 4 - Traditional Chinese
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 5 - Czech
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 6 - Danish
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 7 - Dutch
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 8 - Finnish
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 9 - French
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 10 - German
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 11 - Greek
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 12 - Hungarian
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 13 - Italian
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 14 - Japanese
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 15 - Korean
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 16 - Norwegian
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 17 - Polish
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 18 - Portuguese
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 19 - Brazilian Portuguese
|
||||||
|
u8"Copiar ID",
|
||||||
|
|
||||||
|
// 20 - Romanian
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 21 - Russian
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 22 - Spanish
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 23 - Latin American
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 24 - Swedish
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 25 - Thai
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 26 - Turkish
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 27 - Ukrainian
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 28 - Vietnamese
|
||||||
|
u8"Test achievement",
|
||||||
|
|
||||||
|
// 29 - Croatian
|
||||||
|
u8"Test achievement",
|
||||||
|
};
|
||||||
|
|
||||||
// C:\Program Files (x86)\Steam\tenfoot\resource\localization\tenfoot_*.txt
|
// C:\Program Files (x86)\Steam\tenfoot\resource\localization\tenfoot_*.txt
|
||||||
// Friends_ProfileDetails_Action_InviteToGame
|
// Friends_ProfileDetails_Action_InviteToGame
|
||||||
const char translationInvite[TRANSLATION_NUMBER_OF_LANGUAGES][TRANSLATION_BUFFER_SIZE] = {
|
const char translationInvite[TRANSLATION_NUMBER_OF_LANGUAGES][TRANSLATION_BUFFER_SIZE] = {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include "InGameOverlay/ImGui/imgui.h"
|
#include "InGameOverlay/ImGui/imgui.h"
|
||||||
|
|
||||||
@ -252,6 +253,7 @@ void Steam_Overlay::create_fonts()
|
|||||||
for (int i = 0; i < TRANSLATION_NUMBER_OF_LANGUAGES; i++) {
|
for (int i = 0; i < TRANSLATION_NUMBER_OF_LANGUAGES; i++) {
|
||||||
font_builder.AddText(translationChat[i]);
|
font_builder.AddText(translationChat[i]);
|
||||||
font_builder.AddText(translationCopyId[i]);
|
font_builder.AddText(translationCopyId[i]);
|
||||||
|
font_builder.AddText(translationTestAchievement[i]);
|
||||||
font_builder.AddText(translationInvite[i]);
|
font_builder.AddText(translationInvite[i]);
|
||||||
font_builder.AddText(translationInviteAll[i]);
|
font_builder.AddText(translationInviteAll[i]);
|
||||||
font_builder.AddText(translationJoin[i]);
|
font_builder.AddText(translationJoin[i]);
|
||||||
@ -510,7 +512,7 @@ void Steam_Overlay::notify_sound_user_invite(friend_window_state& friend_state)
|
|||||||
{
|
{
|
||||||
if (settings->disable_overlay_friend_notification) return;
|
if (settings->disable_overlay_friend_notification) return;
|
||||||
|
|
||||||
if (!(friend_state.window_state & window_state_show) || !show_overlay) {
|
if (!(friend_state.window_state & window_state_show)) {
|
||||||
friend_state.window_state |= window_state_need_attention;
|
friend_state.window_state |= window_state_need_attention;
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
auto wav_data = wav_files.find("overlay_friend_notification.wav");
|
auto wav_data = wav_files.find("overlay_friend_notification.wav");
|
||||||
@ -527,7 +529,6 @@ void Steam_Overlay::notify_sound_user_achievement()
|
|||||||
{
|
{
|
||||||
if (settings->disable_overlay_achievement_notification) return;
|
if (settings->disable_overlay_achievement_notification) return;
|
||||||
|
|
||||||
if (!show_overlay) {
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
auto wav_data = wav_files.find("overlay_achievement_notification.wav");
|
auto wav_data = wav_files.find("overlay_achievement_notification.wav");
|
||||||
if (wav_files.end() != wav_data && wav_data->second.size()) {
|
if (wav_files.end() != wav_data && wav_data->second.size()) {
|
||||||
@ -535,7 +536,6 @@ void Steam_Overlay::notify_sound_user_achievement()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Steam_Overlay::notify_sound_auto_accept_friend_invite()
|
void Steam_Overlay::notify_sound_auto_accept_friend_invite()
|
||||||
{
|
{
|
||||||
@ -606,7 +606,7 @@ bool Steam_Overlay::submit_notification(notification_type type, const std::strin
|
|||||||
Notification notif{};
|
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::seconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||||
notif.id = id;
|
notif.id = id;
|
||||||
notif.type = type;
|
notif.type = (uint8)type;
|
||||||
notif.message = msg;
|
notif.message = msg;
|
||||||
notif.frd = frd;
|
notif.frd = frd;
|
||||||
notif.icon = icon;
|
notif.icon = icon;
|
||||||
@ -616,14 +616,14 @@ bool Steam_Overlay::submit_notification(notification_type type, const std::strin
|
|||||||
// uncomment this block to obscure cursor input and steal focus for these specific notifications
|
// uncomment this block to obscure cursor input and steal focus for these specific notifications
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// we want to steal focus for these ones
|
// we want to steal focus for these ones
|
||||||
case notification_type_invite:
|
case notification_type::invite:
|
||||||
obscure_game_input(true);
|
obscure_game_input(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// not effective
|
// not effective
|
||||||
case notification_type_achievement:
|
case notification_type::achievement:
|
||||||
case notification_type_auto_accept_invite:
|
case notification_type::auto_accept_invite:
|
||||||
case notification_type_message:
|
case notification_type::message:
|
||||||
// nothing
|
// nothing
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -641,7 +641,7 @@ void Steam_Overlay::add_chat_message_notification(std::string const &message)
|
|||||||
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
||||||
if (settings->disable_overlay_friend_notification) return;
|
if (settings->disable_overlay_friend_notification) return;
|
||||||
|
|
||||||
submit_notification(notification_type_message, message);
|
submit_notification(notification_type::message, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Steam_Overlay::is_friend_joinable(std::pair<const Friend, friend_window_state> &f)
|
bool Steam_Overlay::is_friend_joinable(std::pair<const Friend, friend_window_state> &f)
|
||||||
@ -834,24 +834,49 @@ void Steam_Overlay::build_friend_window(Friend const& frd, friend_window_state&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set the position of the next notification
|
// set the position of the next notification
|
||||||
void Steam_Overlay::set_next_notification_pos(float width, float height, float font_size, notification_type type, struct NotificationsIndexes &idx)
|
void Steam_Overlay::set_next_notification_pos(float width, float height, const Notification ¬i, struct NotificationsIndexes &idx)
|
||||||
{
|
{
|
||||||
// 0 on the y-axis is top, 0 on the x-axis is left
|
|
||||||
const float noti_width = width * Notification::width_percent;
|
const float noti_width = width * Notification::width_percent;
|
||||||
float noti_height = Notification::height * font_size;
|
|
||||||
|
auto &global_style = ImGui::GetStyle();
|
||||||
|
const float padding_all_sides = 2 * (global_style.WindowPadding.y + global_style.WindowPadding.x);
|
||||||
|
PRINT_DEBUG("%f", padding_all_sides);
|
||||||
|
|
||||||
|
const float msg_height = ImGui::CalcTextSize(
|
||||||
|
noti.message.c_str(),
|
||||||
|
noti.message.c_str() + noti.message.size(),
|
||||||
|
false,
|
||||||
|
noti_width - padding_all_sides - global_style.ItemSpacing.x
|
||||||
|
).y;
|
||||||
|
float noti_height = msg_height + 2 * global_style.WindowPadding.y;
|
||||||
|
|
||||||
// get the required position
|
// get the required position
|
||||||
Overlay_Appearance::NotificationPosition pos = Overlay_Appearance::default_pos;
|
Overlay_Appearance::NotificationPosition pos = Overlay_Appearance::default_pos;
|
||||||
switch (type) {
|
switch ((notification_type)noti.type) {
|
||||||
case notification_type::notification_type_achievement:
|
case notification_type::achievement: {
|
||||||
pos = settings->overlay_appearance.ach_earned_pos;
|
pos = settings->overlay_appearance.ach_earned_pos;
|
||||||
noti_height = settings->overlay_appearance.icon_size + ImGui::GetStyle().FramePadding.y * Notification::height;
|
|
||||||
|
const float new_msg_height = ImGui::CalcTextSize(
|
||||||
|
noti.message.c_str(),
|
||||||
|
noti.message.c_str() + noti.message.size(),
|
||||||
|
false,
|
||||||
|
noti_width - padding_all_sides - global_style.ItemSpacing.x - settings->overlay_appearance.icon_size
|
||||||
|
).y;
|
||||||
|
const float new_noti_height = new_msg_height + 2 * global_style.WindowPadding.y;
|
||||||
|
|
||||||
|
float biggest_noti_height = settings->overlay_appearance.icon_size + 2 * global_style.WindowPadding.y;
|
||||||
|
if (biggest_noti_height < new_noti_height) biggest_noti_height = new_noti_height;
|
||||||
|
|
||||||
|
noti_height = biggest_noti_height;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case notification_type::notification_type_invite: pos = settings->overlay_appearance.invite_pos; break;
|
|
||||||
case notification_type::notification_type_message: pos = settings->overlay_appearance.chat_msg_pos; break;
|
case notification_type::invite: pos = settings->overlay_appearance.invite_pos; break;
|
||||||
|
case notification_type::message: pos = settings->overlay_appearance.chat_msg_pos; break;
|
||||||
default: /* satisfy compiler warning */ break;
|
default: /* satisfy compiler warning */ break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 0 on the y-axis is top, 0 on the x-axis is left
|
||||||
float x = 0.0f;
|
float x = 0.0f;
|
||||||
float y = 0.0f;
|
float y = 0.0f;
|
||||||
switch (pos) {
|
switch (pos) {
|
||||||
@ -910,7 +935,7 @@ void Steam_Overlay::build_notifications(int width, int height)
|
|||||||
for (auto it = notifications.begin(); it != notifications.end(); ++it) {
|
for (auto it = notifications.begin(); it != notifications.end(); ++it) {
|
||||||
auto elapsed_notif = now - it->start_time;
|
auto elapsed_notif = now - it->start_time;
|
||||||
|
|
||||||
set_next_notification_pos(width, height, font_size, (notification_type)it->type, idx);
|
set_next_notification_pos(width, height, *it, idx);
|
||||||
|
|
||||||
if ( elapsed_notif < Notification::fade_in) { // still appearing (fading in)
|
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()));
|
float alpha = settings->overlay_appearance.notification_a * (elapsed_notif.count() / static_cast<float>(Notification::fade_in.count()));
|
||||||
@ -930,16 +955,16 @@ void Steam_Overlay::build_notifications(int width, int height)
|
|||||||
|
|
||||||
// some extra window flags for each notification type
|
// some extra window flags for each notification type
|
||||||
ImGuiWindowFlags extra_flags = ImGuiWindowFlags_NoFocusOnAppearing;
|
ImGuiWindowFlags extra_flags = ImGuiWindowFlags_NoFocusOnAppearing;
|
||||||
switch (it->type) {
|
switch ((notification_type)it->type) {
|
||||||
// games like "Mafia Definitive Edition" will pause the entire game/scene if focus was stolen
|
// games like "Mafia Definitive Edition" will pause the entire game/scene if focus was stolen
|
||||||
// be less intrusive for notifications that do not require interaction
|
// be less intrusive for notifications that do not require interaction
|
||||||
case notification_type_achievement:
|
case notification_type::achievement:
|
||||||
case notification_type_auto_accept_invite:
|
case notification_type::auto_accept_invite:
|
||||||
case notification_type_message:
|
case notification_type::message:
|
||||||
extra_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoInputs;
|
extra_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoInputs;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case notification_type_invite:
|
case notification_type::invite:
|
||||||
// nothing
|
// nothing
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -951,8 +976,8 @@ void Steam_Overlay::build_notifications(int width, int height)
|
|||||||
std::string wnd_name = "NotiPopupShow" + std::to_string(it->id);
|
std::string wnd_name = "NotiPopupShow" + std::to_string(it->id);
|
||||||
if (ImGui::Begin(wnd_name.c_str(), nullptr,
|
if (ImGui::Begin(wnd_name.c_str(), nullptr,
|
||||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | extra_flags)) {
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | extra_flags)) {
|
||||||
switch (it->type) {
|
switch ((notification_type)it->type) {
|
||||||
case notification_type_achievement: {
|
case notification_type::achievement: {
|
||||||
if (!it->icon.expired() && ImGui::BeginTable("imgui_table", 2)) {
|
if (!it->icon.expired() && ImGui::BeginTable("imgui_table", 2)) {
|
||||||
ImGui::TableSetupColumn("imgui_table_image", ImGuiTableColumnFlags_WidthFixed, settings->overlay_appearance.icon_size);
|
ImGui::TableSetupColumn("imgui_table_image", ImGuiTableColumnFlags_WidthFixed, settings->overlay_appearance.icon_size);
|
||||||
ImGui::TableSetupColumn("imgui_table_text");
|
ImGui::TableSetupColumn("imgui_table_text");
|
||||||
@ -971,7 +996,7 @@ void Steam_Overlay::build_notifications(int width, int height)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case notification_type_invite: {
|
case notification_type::invite: {
|
||||||
ImGui::TextWrapped("%s", it->message.c_str());
|
ImGui::TextWrapped("%s", it->message.c_str());
|
||||||
if (ImGui::Button(translationJoin[current_language]))
|
if (ImGui::Button(translationJoin[current_language]))
|
||||||
{
|
{
|
||||||
@ -982,11 +1007,11 @@ void Steam_Overlay::build_notifications(int width, int height)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case notification_type_message:
|
case notification_type::message:
|
||||||
ImGui::TextWrapped("%s", it->message.c_str());
|
ImGui::TextWrapped("%s", it->message.c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case notification_type_auto_accept_invite:
|
case notification_type::auto_accept_invite:
|
||||||
ImGui::TextWrapped("%s", it->message.c_str());
|
ImGui::TextWrapped("%s", it->message.c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1000,25 +1025,26 @@ void Steam_Overlay::build_notifications(int width, int height)
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
ImGui::PopStyleColor(3);
|
ImGui::PopStyleColor(3);
|
||||||
ImGui::PopStyleVar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
// erase all notifications whose visible time exceeded the max
|
// erase all notifications whose visible time exceeded the max
|
||||||
notifications.erase(std::remove_if(notifications.begin(), notifications.end(), [this, &now](Notification &item) {
|
notifications.erase(std::remove_if(notifications.begin(), notifications.end(), [this, &now](Notification &item) {
|
||||||
if ((now - item.start_time) > Notification::show_time) {
|
if ((now - item.start_time) > Notification::show_time) {
|
||||||
PRINT_DEBUG("removing a notification");
|
PRINT_DEBUG("removing a notification");
|
||||||
allow_renderer_frame_processing(false);
|
allow_renderer_frame_processing(false);
|
||||||
// uncomment this block to restore app input focus
|
// uncomment this block to restore app input focus
|
||||||
switch (item.type) {
|
switch ((notification_type)item.type) {
|
||||||
// we want to restore focus for these ones
|
// we want to restore focus for these ones
|
||||||
case notification_type_invite:
|
case notification_type::invite:
|
||||||
obscure_game_input(false);
|
obscure_game_input(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// not effective
|
// not effective
|
||||||
case notification_type_achievement:
|
case notification_type::achievement:
|
||||||
case notification_type_auto_accept_invite:
|
case notification_type::auto_accept_invite:
|
||||||
case notification_type_message:
|
case notification_type::message:
|
||||||
// nothing
|
// nothing
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1050,7 +1076,7 @@ void Steam_Overlay::add_auto_accept_invite_notification()
|
|||||||
char tmp[TRANSLATION_BUFFER_SIZE]{};
|
char tmp[TRANSLATION_BUFFER_SIZE]{};
|
||||||
snprintf(tmp, sizeof(tmp), "%s", translationAutoAcceptFriendInvite[current_language]);
|
snprintf(tmp, sizeof(tmp), "%s", translationAutoAcceptFriendInvite[current_language]);
|
||||||
|
|
||||||
submit_notification(notification_type_auto_accept_invite, tmp);
|
submit_notification(notification_type::auto_accept_invite, tmp);
|
||||||
notify_sound_auto_accept_friend_invite();
|
notify_sound_auto_accept_friend_invite();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1066,7 +1092,23 @@ void Steam_Overlay::add_invite_notification(std::pair<const Friend, friend_windo
|
|||||||
auto &name = first_friend.name();
|
auto &name = first_friend.name();
|
||||||
snprintf(tmp, sizeof(tmp), translationInvitedYouToJoinTheGame[current_language], name.c_str(), (uint64)first_friend.id());
|
snprintf(tmp, sizeof(tmp), translationInvitedYouToJoinTheGame[current_language], name.c_str(), (uint64)first_friend.id());
|
||||||
|
|
||||||
submit_notification(notification_type_invite, tmp, &wnd_state);
|
submit_notification(notification_type::invite, tmp, &wnd_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Steam_Overlay::post_achievement_notification(Overlay_Achievement &ach)
|
||||||
|
{
|
||||||
|
PRINT_DEBUG_ENTRY();
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(overlay_mutex);
|
||||||
|
if (settings->disable_overlay_achievement_notification) return;
|
||||||
|
if (!Ready()) return;
|
||||||
|
|
||||||
|
try_load_ach_icon(ach, true);
|
||||||
|
submit_notification(
|
||||||
|
notification_type::achievement,
|
||||||
|
ach.title + "\n" + ach.description,
|
||||||
|
{},
|
||||||
|
ach.icon
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Steam_Overlay::invite_friend(uint64 friend_id, class Steam_Friends* steamFriends, class Steam_Matchmaking* steamMatchmaking)
|
void Steam_Overlay::invite_friend(uint64 friend_id, class Steam_Friends* steamFriends, class Steam_Matchmaking* steamMatchmaking)
|
||||||
@ -1100,8 +1142,8 @@ bool Steam_Overlay::try_load_ach_icon(Overlay_Achievement &ach, bool achieved)
|
|||||||
file_size = file_size_(file_path);
|
file_size = file_size_(file_path);
|
||||||
}
|
}
|
||||||
if (file_size) {
|
if (file_size) {
|
||||||
std::string img = Local_Storage::load_image_resized(file_path, "", settings->overlay_appearance.icon_size);
|
std::string img(Local_Storage::load_image_resized(file_path, "", settings->overlay_appearance.icon_size));
|
||||||
if (img.length() > 0) {
|
if (img.size()) {
|
||||||
icon_rsrc = _renderer->CreateImageResource(
|
icon_rsrc = _renderer->CreateImageResource(
|
||||||
(void*)img.c_str(),
|
(void*)img.c_str(),
|
||||||
settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size);
|
settings->overlay_appearance.icon_size, settings->overlay_appearance.icon_size);
|
||||||
@ -1249,6 +1291,27 @@ void Steam_Overlay::render_main_window()
|
|||||||
ImGui::SetClipboardText(friend_id_str.c_str());
|
ImGui::SetClipboardText(friend_id_str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
// user clicked on "test achievement"
|
||||||
|
if (ImGui::Button(translationTestAchievement[current_language])) {
|
||||||
|
Overlay_Achievement ach{};
|
||||||
|
ach.title = translationTestAchievement[current_language];
|
||||||
|
ach.description = "~~~ " + ach.title + " ~~~";
|
||||||
|
|
||||||
|
if (achievements.size()) {
|
||||||
|
// https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
|
||||||
|
std::random_device rd{}; // a seed source for the random number engine
|
||||||
|
std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
|
||||||
|
std::uniform_int_distribution<> distrib(0, achievements.size() - 1);
|
||||||
|
|
||||||
|
size_t rand_idx = distrib(gen);
|
||||||
|
ach.icon = achievements[rand_idx].icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
post_achievement_notification(ach);
|
||||||
|
notify_sound_user_achievement();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::LabelText("##label", "%s", translationFriends[current_language]);
|
ImGui::LabelText("##label", "%s", translationFriends[current_language]);
|
||||||
@ -1337,10 +1400,12 @@ void Steam_Overlay::render_main_window()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (achieved) {
|
if (achieved) {
|
||||||
char buffer[80] = {};
|
char buffer[80]{};
|
||||||
time_t unlock_time = (time_t)x.unlock_time;
|
time_t unlock_time = (time_t)x.unlock_time;
|
||||||
// TODO add this format to the overlay_appearance
|
size_t written = std::strftime(buffer, sizeof(buffer), settings->overlay_appearance.ach_unlock_datetime_format.c_str(), std::localtime(&unlock_time));
|
||||||
std::strftime(buffer, 80, "%Y/%m/%d - %H:%M:%S", std::localtime(&unlock_time));
|
if (!written) { // count was reached before the entire string could be stored, keep it safe
|
||||||
|
std::strftime(buffer, sizeof(buffer), "%Y/%m/%d - %H:%M:%S", std::localtime(&unlock_time));
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::TextColored(ImVec4(0, 255, 0, 255), translationAchievedOn[current_language], buffer);
|
ImGui::TextColored(ImVec4(0, 255, 0, 255), translationAchievedOn[current_language], buffer);
|
||||||
} else {
|
} else {
|
||||||
@ -1842,6 +1907,7 @@ void Steam_Overlay::AddAchievementNotification(nlohmann::json const& ach)
|
|||||||
// don't return early when disable_overlay_achievement_notification is true
|
// don't return early when disable_overlay_achievement_notification is true
|
||||||
// otherwise when you open the achievements list/menu you won't see the new unlock status
|
// otherwise when you open the achievements list/menu you won't see the new unlock status
|
||||||
|
|
||||||
|
// adjust the local 'is_achieved' and 'unlock_time'
|
||||||
std::vector<Overlay_Achievement*> found_achs{};
|
std::vector<Overlay_Achievement*> found_achs{};
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock2(global_mutex);
|
std::lock_guard<std::recursive_mutex> lock2(global_mutex);
|
||||||
@ -1860,19 +1926,11 @@ void Steam_Overlay::AddAchievementNotification(nlohmann::json const& ach)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings->disable_overlay_achievement_notification) {
|
|
||||||
for (auto found_ach : found_achs) {
|
for (auto found_ach : found_achs) {
|
||||||
try_load_ach_icon(*found_ach, true);
|
post_achievement_notification(*found_ach);
|
||||||
submit_notification(
|
|
||||||
notification_type_achievement,
|
|
||||||
ach.value("displayName", std::string()) + "\n" + ach.value("description", std::string()),
|
|
||||||
{},
|
|
||||||
found_ach->icon
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_sound_user_achievement();
|
notify_sound_user_achievement();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,8 +47,13 @@ Notification_G=0.15
|
|||||||
Notification_B=0.18
|
Notification_B=0.18
|
||||||
Notification_A=1.0
|
Notification_A=1.0
|
||||||
|
|
||||||
# Notification rounded corners
|
# notification rounded corners
|
||||||
Notification_Rounding=10
|
Notification_Rounding=10.0
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# look for the format here: https://en.cppreference.com/w/cpp/chrono/c/strftime
|
||||||
|
Achievement_Unlock_Datetime_Format=%Y/%m/%d - %H:%M:%S
|
||||||
|
|
||||||
Background_R=-1.0
|
Background_R=-1.0
|
||||||
Background_G=-1.0
|
Background_G=-1.0
|
||||||
|
Loading…
Reference in New Issue
Block a user