mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-06-02 21:05:13 -06:00
ImGui:: Add position and icon arguments for notifications (#4383)
* add position arg * add icon args * fixup * fix the fixup
This commit is contained in:
parent
ac61f4aee2
commit
c79abb6df4
@ -15,17 +15,16 @@ std::optional<NotificationsUI> current_notif;
|
||||
std::queue<NotificationInfo> notif_queue;
|
||||
std::mutex queueMtx;
|
||||
|
||||
const std::map<shadNotifications::stockIcons, std::string> iconMap = {
|
||||
{shadNotifications::stockIcons::shadPS4, "src/images/shadps4.png"},
|
||||
{shadNotifications::stockIcons::Settings, "src/images/big_picture/settings.png"},
|
||||
{shadNotifications::stockIcons::Profiles, "src/images/big_picture/profiles.png"},
|
||||
{shadNotifications::stockIcons::Input, "src/images/big_picture/controller.png"},
|
||||
};
|
||||
|
||||
NotificationsUI::NotificationsUI(NotificationInfo info) {
|
||||
AddLayer(this);
|
||||
|
||||
if (shadIcon.GetTexture().im_id == nullptr) {
|
||||
auto resource = cmrc::res::get_filesystem();
|
||||
auto file = resource.open("src/images/shadps4.png");
|
||||
std::vector<u8> imgdata = std::vector<u8>(file.begin(), file.end());
|
||||
shadIcon = ImGui::RefCountedTexture::DecodePngTexture(imgdata);
|
||||
}
|
||||
|
||||
currentNotification = info;
|
||||
currentInfo = info;
|
||||
|
||||
// Resetting the animation
|
||||
elapsed_time = 0.0f; // Resetting animation time
|
||||
@ -38,32 +37,47 @@ NotificationsUI::~NotificationsUI() {
|
||||
|
||||
void NotificationsUI::Draw() {
|
||||
auto& io = ImGui::GetIO();
|
||||
currentNotification.timer -= io.DeltaTime;
|
||||
currentInfo.timer -= io.DeltaTime;
|
||||
|
||||
float AdjustWidth = io.DisplaySize.x / 1920;
|
||||
float AdjustHeight = io.DisplaySize.y / 1080;
|
||||
|
||||
ImVec2 padding = ImGui::GetStyle().WindowPadding;
|
||||
|
||||
float wrapWidth = 300 * AdjustWidth - padding.x * 2; // 350 window size - 50 image size
|
||||
float textHeight =
|
||||
ImGui::CalcTextSize(currentNotification.message.c_str(), nullptr, false, wrapWidth).y;
|
||||
|
||||
ImGui::CalcTextSize(currentInfo.message.c_str(), nullptr, false, wrapWidth).y;
|
||||
ImVec2 window_size{(350 * AdjustWidth),
|
||||
std::max({70 * AdjustHeight, (textHeight + padding.y * 2.0f)})};
|
||||
|
||||
elapsed_time += io.DeltaTime;
|
||||
float progress = std::min(elapsed_time / animation_duration, 1.0f);
|
||||
float final_pos_x, start_x;
|
||||
float height;
|
||||
|
||||
start_x = io.DisplaySize.x;
|
||||
final_pos_x = io.DisplaySize.x - window_size.x - 20 * AdjustWidth;
|
||||
ImVec2 current_pos = ImVec2(start_x + (final_pos_x - start_x) * progress,
|
||||
io.DisplaySize.y - window_size.y - 50 * AdjustHeight);
|
||||
if (currentInfo.pos == position::TopLeft) {
|
||||
start_x = -window_size.x;
|
||||
final_pos_x = 20 * AdjustWidth;
|
||||
height = 20 * AdjustHeight;
|
||||
} else if (currentInfo.pos == position::TopRight) {
|
||||
start_x = io.DisplaySize.x;
|
||||
final_pos_x = io.DisplaySize.x - window_size.x - 20 * AdjustWidth;
|
||||
height = 20 * AdjustHeight;
|
||||
} else if (currentInfo.pos == position::BottomLeft) {
|
||||
start_x = -window_size.x;
|
||||
final_pos_x = 20 * AdjustWidth;
|
||||
height = io.DisplaySize.y - window_size.y - 20 * AdjustHeight;
|
||||
} else if (currentInfo.pos == position::BottomRight) {
|
||||
start_x = io.DisplaySize.x;
|
||||
final_pos_x = io.DisplaySize.x - window_size.x - 20 * AdjustWidth;
|
||||
height = io.DisplaySize.y - window_size.y - 20 * AdjustHeight;
|
||||
}
|
||||
|
||||
ImVec2 current_pos = ImVec2(start_x + (final_pos_x - start_x) * progress, height);
|
||||
ImGui::SetNextWindowPos(current_pos);
|
||||
|
||||
// If the remaining time of the notif is less than or equal to 1 second, the fade-out begins.
|
||||
if (currentNotification.timer <= 1.0f) {
|
||||
float fade_out_time = 1.0f - (currentNotification.timer / 1.0f);
|
||||
if (currentInfo.timer <= 1.0f) {
|
||||
float fade_out_time = 1.0f - (currentInfo.timer / 1.0f);
|
||||
fade_opacity = 1.0f - fade_out_time;
|
||||
} else {
|
||||
// Fade in , 0 to 1
|
||||
@ -83,19 +97,24 @@ void NotificationsUI::Draw() {
|
||||
ImGuiWindowFlags_NoInputs)) {
|
||||
ImGui::GetColorU32(ImVec4{0.7f});
|
||||
|
||||
if (shadIcon.GetTexture().im_id) {
|
||||
ImGui::Image(shadIcon.GetTexture().im_id,
|
||||
if (currentInfo.icon.GetTexture().im_id) {
|
||||
if (currentInfo.addIconBackground) {
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(
|
||||
pos, ImVec2(pos.x + 50 * AdjustWidth, pos.y + 50 * AdjustHeight),
|
||||
IM_COL32(211, 211, 211, 255));
|
||||
}
|
||||
ImGui::Image(currentInfo.icon.GetTexture().im_id,
|
||||
ImVec2((50 * AdjustWidth), (50 * AdjustHeight)));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::TextWrapped("%s", currentNotification.message.c_str());
|
||||
ImGui::TextWrapped("%s", currentInfo.message.c_str());
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::End();
|
||||
|
||||
if (currentNotification.timer <= 0) {
|
||||
if (currentInfo.timer <= 0) {
|
||||
std::lock_guard<std::mutex> lock(queueMtx);
|
||||
if (!notif_queue.empty()) {
|
||||
NotificationInfo next = notif_queue.front();
|
||||
@ -107,12 +126,31 @@ void NotificationsUI::Draw() {
|
||||
}
|
||||
}
|
||||
|
||||
void QueueNotification(std::string message, float timer) {
|
||||
void QueueNotification(std::string message, float timer, position pos, stockIcons icon) {
|
||||
auto resource = cmrc::res::get_filesystem();
|
||||
auto file = resource.open(iconMap.at(icon));
|
||||
std::vector<u8> imgdata = std::vector<u8>(file.begin(), file.end());
|
||||
|
||||
bool addBackground = false;
|
||||
if (icon == shadNotifications::stockIcons::Input ||
|
||||
icon == shadNotifications::stockIcons::Settings ||
|
||||
icon == shadNotifications::stockIcons::Profiles) {
|
||||
addBackground = true;
|
||||
}
|
||||
|
||||
QueueNotification(message, timer, pos, imgdata, addBackground);
|
||||
}
|
||||
|
||||
void QueueNotification(std::string message, float timer, position pos, std::vector<u8> pngData,
|
||||
bool addBackground) {
|
||||
std::lock_guard<std::mutex> lock(queueMtx);
|
||||
|
||||
NotificationInfo info;
|
||||
info.message = message;
|
||||
info.timer = timer;
|
||||
info.pos = pos;
|
||||
info.icon = ImGui::RefCountedTexture::DecodePngTexture(pngData);
|
||||
info.addIconBackground = addBackground;
|
||||
|
||||
if (!current_notif.has_value()) {
|
||||
current_notif.emplace(info);
|
||||
|
||||
@ -8,9 +8,26 @@
|
||||
|
||||
namespace shadNotifications {
|
||||
|
||||
enum class position {
|
||||
TopLeft,
|
||||
TopRight,
|
||||
BottomLeft,
|
||||
BottomRight,
|
||||
};
|
||||
|
||||
enum class stockIcons {
|
||||
shadPS4,
|
||||
Settings,
|
||||
Profiles,
|
||||
Input,
|
||||
};
|
||||
|
||||
struct NotificationInfo {
|
||||
std::string message;
|
||||
float timer;
|
||||
position pos;
|
||||
ImGui::RefCountedTexture icon;
|
||||
bool addIconBackground; // adds gray background (mostly for black icons)
|
||||
};
|
||||
|
||||
class NotificationsUI final : public ImGui::Layer {
|
||||
@ -21,8 +38,7 @@ public:
|
||||
void Draw() override;
|
||||
|
||||
private:
|
||||
ImGui::RefCountedTexture shadIcon;
|
||||
NotificationInfo currentNotification;
|
||||
NotificationInfo currentInfo;
|
||||
|
||||
// notification animation
|
||||
const float animation_duration = 0.5f; // Animation duration
|
||||
@ -31,6 +47,9 @@ private:
|
||||
float elapsed_time = 0.0f; // Animation time
|
||||
};
|
||||
|
||||
void QueueNotification(std::string message, float timer);
|
||||
void QueueNotification(std::string message, float timer, position pos,
|
||||
stockIcons = shadNotifications::stockIcons::shadPS4);
|
||||
void QueueNotification(std::string message, float timer, position pos, std::vector<u8> pngData,
|
||||
bool iconBackground = false);
|
||||
|
||||
}; // namespace shadNotifications
|
||||
|
||||
@ -453,7 +453,15 @@ static void SavePendingScreenshots(const std::vector<ScreenshotReadback>& readba
|
||||
}
|
||||
|
||||
LOG_INFO(Render_Vulkan, "Saved screenshot: {}", primary_path.string());
|
||||
shadNotifications::QueueNotification("Saved screenshot:\n" + primary_path.string(), 3.0f);
|
||||
|
||||
std::ifstream file(primary_path, std::ios::binary);
|
||||
std::vector<u8> imgdata;
|
||||
if (file) {
|
||||
imgdata = std::vector<u8>(std::istreambuf_iterator<char>(file),
|
||||
std::istreambuf_iterator<char>());
|
||||
}
|
||||
shadNotifications::QueueNotification("Saved screenshot:\n" + primary_path.string(), 3.0f,
|
||||
shadNotifications::position::BottomRight, imgdata);
|
||||
|
||||
for (size_t i = 1; i < readback.paths.size(); ++i) {
|
||||
const auto& path = readback.paths[i];
|
||||
@ -469,7 +477,14 @@ static void SavePendingScreenshots(const std::vector<ScreenshotReadback>& readba
|
||||
}
|
||||
|
||||
LOG_INFO(Render_Vulkan, "Saved screenshot: {}", path.string());
|
||||
shadNotifications::QueueNotification("Saved screenshot:\n" + path.string(), 3.0f);
|
||||
std::ifstream file(path, std::ios::binary);
|
||||
std::vector<u8> imgdata;
|
||||
if (file) {
|
||||
imgdata = std::vector<u8>(std::istreambuf_iterator<char>(file),
|
||||
std::istreambuf_iterator<char>());
|
||||
}
|
||||
shadNotifications::QueueNotification("Saved screenshot:\n" + path.string(), 3.0f,
|
||||
shadNotifications::position::BottomRight, imgdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user