Address cpplint issue "{ should almost always be at the end of the previous line [whitespace/braces] [4]"
This commit is contained in:
parent
63eeb96e71
commit
29f3332276
9 changed files with 152 additions and 304 deletions
|
@ -4,16 +4,13 @@
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
brightray::Notification* NotificationPresenterWin7::CreateNotificationObject(
|
brightray::Notification* NotificationPresenterWin7::CreateNotificationObject(
|
||||||
NotificationDelegate* delegate)
|
NotificationDelegate* delegate) {
|
||||||
{
|
|
||||||
return new Win32Notification(delegate, this);
|
return new Win32Notification(delegate, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Win32Notification* NotificationPresenterWin7::GetNotificationObjectByRef(
|
Win32Notification* NotificationPresenterWin7::GetNotificationObjectByRef(
|
||||||
const DesktopNotificationController::Notification& ref)
|
const DesktopNotificationController::Notification& ref) {
|
||||||
{
|
for(auto n : this->notifications()) {
|
||||||
for(auto n : this->notifications())
|
|
||||||
{
|
|
||||||
auto w32n = static_cast<Win32Notification*>(n);
|
auto w32n = static_cast<Win32Notification*>(n);
|
||||||
if(w32n->GetRef() == ref)
|
if(w32n->GetRef() == ref)
|
||||||
return w32n;
|
return w32n;
|
||||||
|
@ -23,10 +20,8 @@ Win32Notification* NotificationPresenterWin7::GetNotificationObjectByRef(
|
||||||
}
|
}
|
||||||
|
|
||||||
Win32Notification* NotificationPresenterWin7::GetNotificationObjectByTag(
|
Win32Notification* NotificationPresenterWin7::GetNotificationObjectByTag(
|
||||||
const std::string& tag)
|
const std::string& tag) {
|
||||||
{
|
for(auto n : this->notifications()) {
|
||||||
for(auto n : this->notifications())
|
|
||||||
{
|
|
||||||
auto w32n = static_cast<Win32Notification*>(n);
|
auto w32n = static_cast<Win32Notification*>(n);
|
||||||
if(w32n->GetTag() == tag)
|
if(w32n->GetTag() == tag)
|
||||||
return w32n;
|
return w32n;
|
||||||
|
@ -36,15 +31,13 @@ Win32Notification* NotificationPresenterWin7::GetNotificationObjectByTag(
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationPresenterWin7::OnNotificationClicked(
|
void NotificationPresenterWin7::OnNotificationClicked(
|
||||||
Notification& notification)
|
Notification& notification) {
|
||||||
{
|
|
||||||
auto n = GetNotificationObjectByRef(notification);
|
auto n = GetNotificationObjectByRef(notification);
|
||||||
if(n) n->NotificationClicked();
|
if(n) n->NotificationClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationPresenterWin7::OnNotificationDismissed(
|
void NotificationPresenterWin7::OnNotificationDismissed(
|
||||||
Notification& notification)
|
Notification& notification) {
|
||||||
{
|
|
||||||
auto n = GetNotificationObjectByRef(notification);
|
auto n = GetNotificationObjectByRef(notification);
|
||||||
if(n) n->NotificationDismissed();
|
if(n) n->NotificationDismissed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,7 @@ class Win32Notification;
|
||||||
|
|
||||||
class NotificationPresenterWin7 :
|
class NotificationPresenterWin7 :
|
||||||
public NotificationPresenter,
|
public NotificationPresenter,
|
||||||
public DesktopNotificationController
|
public DesktopNotificationController {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
NotificationPresenterWin7() = default;
|
NotificationPresenterWin7() = default;
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
struct NotificationData
|
struct NotificationData {
|
||||||
{
|
|
||||||
DesktopNotificationController* controller = nullptr;
|
DesktopNotificationController* controller = nullptr;
|
||||||
|
|
||||||
std::wstring caption;
|
std::wstring caption;
|
||||||
|
@ -14,8 +13,7 @@ struct NotificationData
|
||||||
|
|
||||||
NotificationData() = default;
|
NotificationData() = default;
|
||||||
|
|
||||||
~NotificationData()
|
~NotificationData() {
|
||||||
{
|
|
||||||
if(image) DeleteObject(image);
|
if(image) DeleteObject(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,23 +22,19 @@ struct NotificationData
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T ScaleForDpi(T value, unsigned dpi)
|
inline T ScaleForDpi(T value, unsigned dpi) {
|
||||||
{
|
|
||||||
return value * dpi / 96;
|
return value * dpi / 96;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ScreenMetrics
|
struct ScreenMetrics {
|
||||||
{
|
|
||||||
UINT dpi_x, dpi_y;
|
UINT dpi_x, dpi_y;
|
||||||
|
|
||||||
ScreenMetrics()
|
ScreenMetrics() {
|
||||||
{
|
|
||||||
typedef HRESULT WINAPI GetDpiForMonitor_t(HMONITOR, int, UINT*, UINT*);
|
typedef HRESULT WINAPI GetDpiForMonitor_t(HMONITOR, int, UINT*, UINT*);
|
||||||
auto GetDpiForMonitor =
|
auto GetDpiForMonitor =
|
||||||
(GetDpiForMonitor_t*)GetProcAddress(GetModuleHandle(TEXT("shcore")),
|
(GetDpiForMonitor_t*)GetProcAddress(GetModuleHandle(TEXT("shcore")),
|
||||||
"GetDpiForMonitor");
|
"GetDpiForMonitor");
|
||||||
if(GetDpiForMonitor)
|
if(GetDpiForMonitor) {
|
||||||
{
|
|
||||||
auto monitor = MonitorFromPoint({}, MONITOR_DEFAULTTOPRIMARY);
|
auto monitor = MonitorFromPoint({}, MONITOR_DEFAULTTOPRIMARY);
|
||||||
if(GetDpiForMonitor(monitor, 0, &dpi_x, &dpi_y) == S_OK)
|
if(GetDpiForMonitor(monitor, 0, &dpi_x, &dpi_y) == S_OK)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,19 +12,16 @@ using std::shared_ptr;
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
HBITMAP CopyBitmap(HBITMAP bitmap)
|
HBITMAP CopyBitmap(HBITMAP bitmap) {
|
||||||
{
|
|
||||||
HBITMAP ret = NULL;
|
HBITMAP ret = NULL;
|
||||||
|
|
||||||
BITMAP bm;
|
BITMAP bm;
|
||||||
if(bitmap && GetObject(bitmap, sizeof(bm), &bm))
|
if(bitmap && GetObject(bitmap, sizeof(bm), &bm)) {
|
||||||
{
|
|
||||||
HDC hdcScreen = GetDC(NULL);
|
HDC hdcScreen = GetDC(NULL);
|
||||||
ret = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
|
ret = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
|
||||||
ReleaseDC(NULL, hdcScreen);
|
ReleaseDC(NULL, hdcScreen);
|
||||||
|
|
||||||
if(ret)
|
if(ret) {
|
||||||
{
|
|
||||||
HDC hdcSrc = CreateCompatibleDC(NULL);
|
HDC hdcSrc = CreateCompatibleDC(NULL);
|
||||||
HDC hdcDst = CreateCompatibleDC(NULL);
|
HDC hdcDst = CreateCompatibleDC(NULL);
|
||||||
SelectBitmap(hdcSrc, bitmap);
|
SelectBitmap(hdcSrc, bitmap);
|
||||||
|
@ -39,8 +36,7 @@ HBITMAP CopyBitmap(HBITMAP bitmap)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
HINSTANCE DesktopNotificationController::RegisterWndClasses()
|
HINSTANCE DesktopNotificationController::RegisterWndClasses() {
|
||||||
{
|
|
||||||
// We keep a static `module` variable which serves a dual purpose:
|
// We keep a static `module` variable which serves a dual purpose:
|
||||||
// 1. Stores the HINSTANCE where the window classes are registered,
|
// 1. Stores the HINSTANCE where the window classes are registered,
|
||||||
// which can be passed to `CreateWindow`
|
// which can be passed to `CreateWindow`
|
||||||
|
@ -49,13 +45,11 @@ HINSTANCE DesktopNotificationController::RegisterWndClasses()
|
||||||
// as there is no point).
|
// as there is no point).
|
||||||
static HMODULE module = NULL;
|
static HMODULE module = NULL;
|
||||||
|
|
||||||
if(!module)
|
if(!module) {
|
||||||
{
|
|
||||||
if(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
if(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||||
reinterpret_cast<LPCWSTR>(&RegisterWndClasses),
|
reinterpret_cast<LPCWSTR>(&RegisterWndClasses),
|
||||||
&module))
|
&module)) {
|
||||||
{
|
|
||||||
Toast::Register(module);
|
Toast::Register(module);
|
||||||
|
|
||||||
WNDCLASSEX wc = { sizeof(wc) };
|
WNDCLASSEX wc = { sizeof(wc) };
|
||||||
|
@ -72,23 +66,19 @@ HINSTANCE DesktopNotificationController::RegisterWndClasses()
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopNotificationController::DesktopNotificationController(
|
DesktopNotificationController::DesktopNotificationController(
|
||||||
unsigned maximumToasts)
|
unsigned maximumToasts) {
|
||||||
{
|
|
||||||
instances_.reserve(maximumToasts);
|
instances_.reserve(maximumToasts);
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopNotificationController::~DesktopNotificationController()
|
DesktopNotificationController::~DesktopNotificationController() {
|
||||||
{
|
|
||||||
for(auto&& inst : instances_) DestroyToast(inst);
|
for(auto&& inst : instances_) DestroyToast(inst);
|
||||||
if(hwnd_controller_) DestroyWindow(hwnd_controller_);
|
if(hwnd_controller_) DestroyWindow(hwnd_controller_);
|
||||||
ClearAssets();
|
ClearAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK DesktopNotificationController::WndProc(
|
LRESULT CALLBACK DesktopNotificationController::WndProc(
|
||||||
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||||
{
|
switch(message) {
|
||||||
switch(message)
|
|
||||||
{
|
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
auto& cs = reinterpret_cast<const CREATESTRUCT*&>(lParam);
|
auto& cs = reinterpret_cast<const CREATESTRUCT*&>(lParam);
|
||||||
|
@ -97,8 +87,7 @@ LRESULT CALLBACK DesktopNotificationController::WndProc(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_TIMER:
|
case WM_TIMER:
|
||||||
if(wParam == TimerID_Animate)
|
if(wParam == TimerID_Animate) {
|
||||||
{
|
|
||||||
Get(hWnd)->AnimateAll();
|
Get(hWnd)->AnimateAll();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -112,8 +101,7 @@ LRESULT CALLBACK DesktopNotificationController::WndProc(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SETTINGCHANGE:
|
case WM_SETTINGCHANGE:
|
||||||
if(wParam == SPI_SETWORKAREA)
|
if(wParam == SPI_SETWORKAREA) {
|
||||||
{
|
|
||||||
Get(hWnd)->AnimateAll();
|
Get(hWnd)->AnimateAll();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -122,12 +110,10 @@ LRESULT CALLBACK DesktopNotificationController::WndProc(
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::StartAnimation()
|
void DesktopNotificationController::StartAnimation() {
|
||||||
{
|
|
||||||
_ASSERT(hwnd_controller_);
|
_ASSERT(hwnd_controller_);
|
||||||
|
|
||||||
if(!is_animating_ && hwnd_controller_)
|
if(!is_animating_ && hwnd_controller_) {
|
||||||
{
|
|
||||||
// NOTE: 15ms is shorter than what we'd need for 60 fps, but since
|
// NOTE: 15ms is shorter than what we'd need for 60 fps, but since
|
||||||
// the timer is not accurate we must request a higher frame rate
|
// the timer is not accurate we must request a higher frame rate
|
||||||
// to get at least 60
|
// to get at least 60
|
||||||
|
@ -137,25 +123,20 @@ void DesktopNotificationController::StartAnimation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HFONT DesktopNotificationController::GetCaptionFont()
|
HFONT DesktopNotificationController::GetCaptionFont() {
|
||||||
{
|
|
||||||
InitializeFonts();
|
InitializeFonts();
|
||||||
return caption_font_;
|
return caption_font_;
|
||||||
}
|
}
|
||||||
|
|
||||||
HFONT DesktopNotificationController::GetBodyFont()
|
HFONT DesktopNotificationController::GetBodyFont() {
|
||||||
{
|
|
||||||
InitializeFonts();
|
InitializeFonts();
|
||||||
return body_font_;
|
return body_font_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::InitializeFonts()
|
void DesktopNotificationController::InitializeFonts() {
|
||||||
{
|
if(!body_font_) {
|
||||||
if(!body_font_)
|
|
||||||
{
|
|
||||||
NONCLIENTMETRICS metrics = { sizeof(metrics) };
|
NONCLIENTMETRICS metrics = { sizeof(metrics) };
|
||||||
if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrics, 0))
|
if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrics, 0)) {
|
||||||
{
|
|
||||||
auto baseHeight = metrics.lfMessageFont.lfHeight;
|
auto baseHeight = metrics.lfMessageFont.lfHeight;
|
||||||
|
|
||||||
HDC hdc = GetDC(NULL);
|
HDC hdc = GetDC(NULL);
|
||||||
|
@ -174,32 +155,27 @@ void DesktopNotificationController::InitializeFonts()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::ClearAssets()
|
void DesktopNotificationController::ClearAssets() {
|
||||||
{
|
|
||||||
if(caption_font_) { DeleteFont(caption_font_); caption_font_ = NULL; }
|
if(caption_font_) { DeleteFont(caption_font_); caption_font_ = NULL; }
|
||||||
if(body_font_) { DeleteFont(body_font_); body_font_ = NULL; }
|
if(body_font_) { DeleteFont(body_font_); body_font_ = NULL; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::AnimateAll()
|
void DesktopNotificationController::AnimateAll() {
|
||||||
{
|
|
||||||
// NOTE: This function refreshes position and size of all toasts according
|
// NOTE: This function refreshes position and size of all toasts according
|
||||||
// to all current conditions. Animation time is only one of the variables
|
// to all current conditions. Animation time is only one of the variables
|
||||||
// influencing them. Screen resolution is another.
|
// influencing them. Screen resolution is another.
|
||||||
|
|
||||||
bool keepAnimating = false;
|
bool keepAnimating = false;
|
||||||
|
|
||||||
if(!instances_.empty())
|
if(!instances_.empty()) {
|
||||||
{
|
|
||||||
RECT workArea;
|
RECT workArea;
|
||||||
if(SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0))
|
if(SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0)) {
|
||||||
{
|
|
||||||
ScreenMetrics metrics;
|
ScreenMetrics metrics;
|
||||||
POINT origin = { workArea.right,
|
POINT origin = { workArea.right,
|
||||||
workArea.bottom - metrics.Y(toast_margin_<int>) };
|
workArea.bottom - metrics.Y(toast_margin_<int>) };
|
||||||
|
|
||||||
auto hdwp = BeginDeferWindowPos((int)instances_.size());
|
auto hdwp = BeginDeferWindowPos((int)instances_.size());
|
||||||
for(auto&& inst : instances_)
|
for(auto&& inst : instances_) {
|
||||||
{
|
|
||||||
if(!inst.hwnd) continue;
|
if(!inst.hwnd) continue;
|
||||||
|
|
||||||
auto notification = Toast::Get(inst.hwnd);
|
auto notification = Toast::Get(inst.hwnd);
|
||||||
|
@ -211,8 +187,7 @@ void DesktopNotificationController::AnimateAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!keepAnimating)
|
if(!keepAnimating) {
|
||||||
{
|
|
||||||
_ASSERT(hwnd_controller_);
|
_ASSERT(hwnd_controller_);
|
||||||
if(hwnd_controller_) KillTimer(hwnd_controller_, TimerID_Animate);
|
if(hwnd_controller_) KillTimer(hwnd_controller_, TimerID_Animate);
|
||||||
is_animating_ = false;
|
is_animating_ = false;
|
||||||
|
@ -220,8 +195,7 @@ void DesktopNotificationController::AnimateAll()
|
||||||
|
|
||||||
// Purge dismissed notifications and collapse the stack between
|
// Purge dismissed notifications and collapse the stack between
|
||||||
// items which are highlighted
|
// items which are highlighted
|
||||||
if(!instances_.empty())
|
if(!instances_.empty()) {
|
||||||
{
|
|
||||||
auto isAlive = [](ToastInstance& inst) {
|
auto isAlive = [](ToastInstance& inst) {
|
||||||
return inst.hwnd && IsWindowVisible(inst.hwnd);
|
return inst.hwnd && IsWindowVisible(inst.hwnd);
|
||||||
};
|
};
|
||||||
|
@ -230,8 +204,7 @@ void DesktopNotificationController::AnimateAll()
|
||||||
return inst.hwnd && Toast::Get(inst.hwnd)->IsHighlighted();
|
return inst.hwnd && Toast::Get(inst.hwnd)->IsHighlighted();
|
||||||
};
|
};
|
||||||
|
|
||||||
for(auto it = instances_.begin();; ++it)
|
for(auto it = instances_.begin();; ++it) {
|
||||||
{
|
|
||||||
// find next highlighted item
|
// find next highlighted item
|
||||||
auto it2 = find_if(it, instances_.end(), isHighlighted);
|
auto it2 = find_if(it, instances_.end(), isHighlighted);
|
||||||
|
|
||||||
|
@ -241,8 +214,7 @@ void DesktopNotificationController::AnimateAll()
|
||||||
// purge the dead items
|
// purge the dead items
|
||||||
for_each(it, it2, [this](auto&& inst) { DestroyToast(inst); });
|
for_each(it, it2, [this](auto&& inst) { DestroyToast(inst); });
|
||||||
|
|
||||||
if(it2 == instances_.end())
|
if(it2 == instances_.end()) {
|
||||||
{
|
|
||||||
instances_.erase(it, it2);
|
instances_.erase(it, it2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -252,16 +224,13 @@ void DesktopNotificationController::AnimateAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new toast positions
|
// Set new toast positions
|
||||||
if(!instances_.empty())
|
if(!instances_.empty()) {
|
||||||
{
|
|
||||||
ScreenMetrics metrics;
|
ScreenMetrics metrics;
|
||||||
auto margin = metrics.Y(toast_margin_<int>);
|
auto margin = metrics.Y(toast_margin_<int>);
|
||||||
|
|
||||||
int targetPos = 0;
|
int targetPos = 0;
|
||||||
for(auto&& inst : instances_)
|
for(auto&& inst : instances_) {
|
||||||
{
|
if(inst.hwnd) {
|
||||||
if(inst.hwnd)
|
|
||||||
{
|
|
||||||
auto toast = Toast::Get(inst.hwnd);
|
auto toast = Toast::Get(inst.hwnd);
|
||||||
|
|
||||||
if(toast->IsHighlighted())
|
if(toast->IsHighlighted())
|
||||||
|
@ -280,8 +249,7 @@ void DesktopNotificationController::AnimateAll()
|
||||||
|
|
||||||
DesktopNotificationController::Notification
|
DesktopNotificationController::Notification
|
||||||
DesktopNotificationController::AddNotification(
|
DesktopNotificationController::AddNotification(
|
||||||
std::wstring caption, std::wstring bodyText, HBITMAP image)
|
std::wstring caption, std::wstring bodyText, HBITMAP image) {
|
||||||
{
|
|
||||||
NotificationLink data(this);
|
NotificationLink data(this);
|
||||||
|
|
||||||
data->caption = move(caption);
|
data->caption = move(caption);
|
||||||
|
@ -295,12 +263,10 @@ DesktopNotificationController::Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::CloseNotification(
|
void DesktopNotificationController::CloseNotification(
|
||||||
Notification& notification)
|
Notification& notification) {
|
||||||
{
|
|
||||||
// Remove it from the queue
|
// Remove it from the queue
|
||||||
auto it = find(queue_.begin(), queue_.end(), notification.data_);
|
auto it = find(queue_.begin(), queue_.end(), notification.data_);
|
||||||
if(it != queue_.end())
|
if(it != queue_.end()) {
|
||||||
{
|
|
||||||
queue_.erase(it);
|
queue_.erase(it);
|
||||||
this->OnNotificationClosed(notification);
|
this->OnNotificationClosed(notification);
|
||||||
return;
|
return;
|
||||||
|
@ -308,31 +274,25 @@ void DesktopNotificationController::CloseNotification(
|
||||||
|
|
||||||
// Dismiss active toast
|
// Dismiss active toast
|
||||||
auto hwnd = GetToast(notification.data_.get());
|
auto hwnd = GetToast(notification.data_.get());
|
||||||
if(hwnd)
|
if(hwnd) {
|
||||||
{
|
|
||||||
auto toast = Toast::Get(hwnd);
|
auto toast = Toast::Get(hwnd);
|
||||||
toast->Dismiss();
|
toast->Dismiss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::CheckQueue()
|
void DesktopNotificationController::CheckQueue() {
|
||||||
{
|
while(instances_.size() < instances_.capacity() && !queue_.empty()) {
|
||||||
while(instances_.size() < instances_.capacity() && !queue_.empty())
|
|
||||||
{
|
|
||||||
CreateToast(move(queue_.front()));
|
CreateToast(move(queue_.front()));
|
||||||
queue_.pop_front();
|
queue_.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::CreateToast(NotificationLink&& data)
|
void DesktopNotificationController::CreateToast(NotificationLink&& data) {
|
||||||
{
|
|
||||||
auto hInstance = RegisterWndClasses();
|
auto hInstance = RegisterWndClasses();
|
||||||
auto hwnd = Toast::Create(hInstance, data);
|
auto hwnd = Toast::Create(hInstance, data);
|
||||||
if(hwnd)
|
if(hwnd) {
|
||||||
{
|
|
||||||
int toastPos = 0;
|
int toastPos = 0;
|
||||||
if(!instances_.empty())
|
if(!instances_.empty()) {
|
||||||
{
|
|
||||||
auto& item = instances_.back();
|
auto& item = instances_.back();
|
||||||
_ASSERT(item.hwnd);
|
_ASSERT(item.hwnd);
|
||||||
|
|
||||||
|
@ -345,8 +305,7 @@ void DesktopNotificationController::CreateToast(NotificationLink&& data)
|
||||||
|
|
||||||
instances_.push_back({ hwnd, move(data) });
|
instances_.push_back({ hwnd, move(data) });
|
||||||
|
|
||||||
if(!hwnd_controller_)
|
if(!hwnd_controller_) {
|
||||||
{
|
|
||||||
// NOTE: We cannot use a message-only window because we need to
|
// NOTE: We cannot use a message-only window because we need to
|
||||||
// receive system notifications
|
// receive system notifications
|
||||||
hwnd_controller_ = CreateWindow(class_name_, nullptr, 0,
|
hwnd_controller_ = CreateWindow(class_name_, nullptr, 0,
|
||||||
|
@ -360,8 +319,7 @@ void DesktopNotificationController::CreateToast(NotificationLink&& data)
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND DesktopNotificationController::GetToast(
|
HWND DesktopNotificationController::GetToast(
|
||||||
const NotificationData* data) const
|
const NotificationData* data) const {
|
||||||
{
|
|
||||||
auto it = find_if(instances_.cbegin(), instances_.cend(),
|
auto it = find_if(instances_.cbegin(), instances_.cend(),
|
||||||
[data](auto&& inst) {
|
[data](auto&& inst) {
|
||||||
auto toast = Toast::Get(inst.hwnd);
|
auto toast = Toast::Get(inst.hwnd);
|
||||||
|
@ -371,10 +329,8 @@ HWND DesktopNotificationController::GetToast(
|
||||||
return (it != instances_.cend()) ? it->hwnd : NULL;
|
return (it != instances_.cend()) ? it->hwnd : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::DestroyToast(ToastInstance& inst)
|
void DesktopNotificationController::DestroyToast(ToastInstance& inst) {
|
||||||
{
|
if(inst.hwnd) {
|
||||||
if(inst.hwnd)
|
|
||||||
{
|
|
||||||
auto data = Toast::Get(inst.hwnd)->GetNotification();
|
auto data = Toast::Get(inst.hwnd)->GetNotification();
|
||||||
|
|
||||||
DestroyWindow(inst.hwnd);
|
DestroyWindow(inst.hwnd);
|
||||||
|
@ -388,19 +344,16 @@ void DesktopNotificationController::DestroyToast(ToastInstance& inst)
|
||||||
|
|
||||||
DesktopNotificationController::Notification::Notification(
|
DesktopNotificationController::Notification::Notification(
|
||||||
const shared_ptr<NotificationData>& data) :
|
const shared_ptr<NotificationData>& data) :
|
||||||
data_(data)
|
data_(data) {
|
||||||
{
|
|
||||||
_ASSERT(data != nullptr);
|
_ASSERT(data != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DesktopNotificationController::Notification::operator==(
|
bool DesktopNotificationController::Notification::operator==(
|
||||||
const Notification& other) const
|
const Notification& other) const {
|
||||||
{
|
|
||||||
return data_ == other.data_;
|
return data_ == other.data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Notification::Close()
|
void DesktopNotificationController::Notification::Close() {
|
||||||
{
|
|
||||||
// No business calling this when not pointing to a valid instance
|
// No business calling this when not pointing to a valid instance
|
||||||
_ASSERT(data_);
|
_ASSERT(data_);
|
||||||
|
|
||||||
|
@ -409,8 +362,7 @@ void DesktopNotificationController::Notification::Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Notification::Set(
|
void DesktopNotificationController::Notification::Set(
|
||||||
std::wstring caption, std::wstring bodyText, HBITMAP image)
|
std::wstring caption, std::wstring bodyText, HBITMAP image) {
|
||||||
{
|
|
||||||
// No business calling this when not pointing to a valid instance
|
// No business calling this when not pointing to a valid instance
|
||||||
_ASSERT(data_);
|
_ASSERT(data_);
|
||||||
|
|
||||||
|
@ -425,8 +377,7 @@ void DesktopNotificationController::Notification::Set(
|
||||||
data_->image = CopyBitmap(image);
|
data_->image = CopyBitmap(image);
|
||||||
|
|
||||||
auto hwnd = data_->controller->GetToast(data_.get());
|
auto hwnd = data_->controller->GetToast(data_.get());
|
||||||
if(hwnd)
|
if(hwnd) {
|
||||||
{
|
|
||||||
auto toast = Toast::Get(hwnd);
|
auto toast = Toast::Get(hwnd);
|
||||||
toast->ResetContents();
|
toast->ResetContents();
|
||||||
}
|
}
|
||||||
|
@ -438,13 +389,11 @@ void DesktopNotificationController::Notification::Set(
|
||||||
|
|
||||||
DesktopNotificationController::NotificationLink::NotificationLink(
|
DesktopNotificationController::NotificationLink::NotificationLink(
|
||||||
DesktopNotificationController* controller) :
|
DesktopNotificationController* controller) :
|
||||||
shared_ptr(make_shared<NotificationData>())
|
shared_ptr(make_shared<NotificationData>()) {
|
||||||
{
|
|
||||||
get()->controller = controller;
|
get()->controller = controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopNotificationController::NotificationLink::~NotificationLink()
|
DesktopNotificationController::NotificationLink::~NotificationLink() {
|
||||||
{
|
|
||||||
auto p = get();
|
auto p = get();
|
||||||
if(p) p->controller = nullptr;
|
if(p) p->controller = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@ namespace brightray {
|
||||||
|
|
||||||
struct NotificationData;
|
struct NotificationData;
|
||||||
|
|
||||||
class DesktopNotificationController
|
class DesktopNotificationController {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
DesktopNotificationController(unsigned maximumToasts = 3);
|
DesktopNotificationController(unsigned maximumToasts = 3);
|
||||||
~DesktopNotificationController();
|
~DesktopNotificationController();
|
||||||
|
@ -61,8 +60,7 @@ private:
|
||||||
|
|
||||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
|
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
|
||||||
WPARAM wParam, LPARAM lParam);
|
WPARAM wParam, LPARAM lParam);
|
||||||
static DesktopNotificationController* Get(HWND hWnd)
|
static DesktopNotificationController* Get(HWND hWnd) {
|
||||||
{
|
|
||||||
return reinterpret_cast<DesktopNotificationController*>(
|
return reinterpret_cast<DesktopNotificationController*>(
|
||||||
GetWindowLongPtr(hWnd, 0));
|
GetWindowLongPtr(hWnd, 0));
|
||||||
}
|
}
|
||||||
|
@ -89,8 +87,7 @@ private:
|
||||||
bool is_animating_ = false;
|
bool is_animating_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DesktopNotificationController::Notification
|
class DesktopNotificationController::Notification {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Notification() = default;
|
Notification() = default;
|
||||||
Notification(const std::shared_ptr<NotificationData>& data);
|
Notification(const std::shared_ptr<NotificationData>& data);
|
||||||
|
|
|
@ -13,24 +13,20 @@ using std::shared_ptr;
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
static COLORREF GetAccentColor()
|
static COLORREF GetAccentColor() {
|
||||||
{
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if(IsAppThemed())
|
if(IsAppThemed()) {
|
||||||
{
|
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
if(RegOpenKeyEx(HKEY_CURRENT_USER,
|
if(RegOpenKeyEx(HKEY_CURRENT_USER,
|
||||||
TEXT("SOFTWARE\\Microsoft\\Windows\\DWM"), 0,
|
TEXT("SOFTWARE\\Microsoft\\Windows\\DWM"), 0,
|
||||||
KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
|
KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) {
|
||||||
{
|
|
||||||
COLORREF color;
|
COLORREF color;
|
||||||
DWORD type, size;
|
DWORD type, size;
|
||||||
if(RegQueryValueEx(hkey, TEXT("AccentColor"), nullptr,
|
if(RegQueryValueEx(hkey, TEXT("AccentColor"), nullptr,
|
||||||
&type,
|
&type,
|
||||||
(BYTE*)&color,
|
(BYTE*)&color,
|
||||||
&(size = sizeof(color))) == ERROR_SUCCESS &&
|
&(size = sizeof(color))) == ERROR_SUCCESS &&
|
||||||
type == REG_DWORD)
|
type == REG_DWORD) {
|
||||||
{
|
|
||||||
// convert from RGBA
|
// convert from RGBA
|
||||||
color = RGB(GetRValue(color),
|
color = RGB(GetRValue(color),
|
||||||
GetGValue(color),
|
GetGValue(color),
|
||||||
|
@ -41,8 +37,7 @@ static COLORREF GetAccentColor()
|
||||||
&type,
|
&type,
|
||||||
(BYTE*)&color,
|
(BYTE*)&color,
|
||||||
&(size = sizeof(color))) == ERROR_SUCCESS &&
|
&(size = sizeof(color))) == ERROR_SUCCESS &&
|
||||||
type == REG_DWORD)
|
type == REG_DWORD) {
|
||||||
{
|
|
||||||
// convert from BGRA
|
// convert from BGRA
|
||||||
color = RGB(GetBValue(color),
|
color = RGB(GetBValue(color),
|
||||||
GetGValue(color),
|
GetGValue(color),
|
||||||
|
@ -60,8 +55,7 @@ static COLORREF GetAccentColor()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stretches a bitmap to the specified size, preserves alpha channel
|
// Stretches a bitmap to the specified size, preserves alpha channel
|
||||||
static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height)
|
static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height) {
|
||||||
{
|
|
||||||
// We use StretchBlt for the scaling, but that discards the alpha channel.
|
// We use StretchBlt for the scaling, but that discards the alpha channel.
|
||||||
// So we first create a separate grayscale bitmap from the alpha channel,
|
// So we first create a separate grayscale bitmap from the alpha channel,
|
||||||
// scale that separately, and copy it back to the scaled color bitmap.
|
// scale that separately, and copy it back to the scaled color bitmap.
|
||||||
|
@ -91,17 +85,14 @@ static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height)
|
||||||
DIB_RGB_COLORS, &alphaSrcBits,
|
DIB_RGB_COLORS, &alphaSrcBits,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
|
||||||
if(alphaSrcBitmap)
|
if(alphaSrcBitmap) {
|
||||||
{
|
|
||||||
if(GetDIBits(hdcScreen, bitmap, 0, 0, 0,
|
if(GetDIBits(hdcScreen, bitmap, 0, 0, 0,
|
||||||
(BITMAPINFO*)&bmi, DIB_RGB_COLORS) &&
|
(BITMAPINFO*)&bmi, DIB_RGB_COLORS) &&
|
||||||
bmi.biSizeImage > 0 &&
|
bmi.biSizeImage > 0 &&
|
||||||
(bmi.biSizeImage % 4) == 0)
|
(bmi.biSizeImage % 4) == 0) {
|
||||||
{
|
|
||||||
auto buf = (BYTE*)_aligned_malloc(bmi.biSizeImage,
|
auto buf = (BYTE*)_aligned_malloc(bmi.biSizeImage,
|
||||||
sizeof(DWORD));
|
sizeof(DWORD));
|
||||||
if(buf)
|
if(buf) {
|
||||||
{
|
|
||||||
GetDIBits(hdcScreen, bitmap, 0, bm.bmHeight, buf,
|
GetDIBits(hdcScreen, bitmap, 0, bm.bmHeight, buf,
|
||||||
(BITMAPINFO*)&bmi, DIB_RGB_COLORS);
|
(BITMAPINFO*)&bmi, DIB_RGB_COLORS);
|
||||||
|
|
||||||
|
@ -109,8 +100,7 @@ static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height)
|
||||||
for(const DWORD *src = (DWORD*)buf,
|
for(const DWORD *src = (DWORD*)buf,
|
||||||
*end = (DWORD*)(buf + bmi.biSizeImage);
|
*end = (DWORD*)(buf + bmi.biSizeImage);
|
||||||
src != end;
|
src != end;
|
||||||
++src, ++dest)
|
++src, ++dest) {
|
||||||
{
|
|
||||||
BYTE a = *src >> 24;
|
BYTE a = *src >> 24;
|
||||||
*dest++ = a;
|
*dest++ = a;
|
||||||
*dest++ = a;
|
*dest++ = a;
|
||||||
|
@ -123,8 +113,7 @@ static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(alphaSrcBitmap)
|
if(alphaSrcBitmap) {
|
||||||
{
|
|
||||||
BITMAPINFOHEADER bmi = { sizeof(BITMAPINFOHEADER) };
|
BITMAPINFOHEADER bmi = { sizeof(BITMAPINFOHEADER) };
|
||||||
bmi.biWidth = width;
|
bmi.biWidth = width;
|
||||||
bmi.biHeight = height;
|
bmi.biHeight = height;
|
||||||
|
@ -145,8 +134,7 @@ static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height)
|
||||||
HDC hdc = CreateCompatibleDC(NULL);
|
HDC hdc = CreateCompatibleDC(NULL);
|
||||||
HDC hdcSrc = CreateCompatibleDC(NULL);
|
HDC hdcSrc = CreateCompatibleDC(NULL);
|
||||||
|
|
||||||
if(colorBitmap && alphaBitmap && hdc && hdcSrc)
|
if(colorBitmap && alphaBitmap && hdc && hdcSrc) {
|
||||||
{
|
|
||||||
SetStretchBltMode(hdc, HALFTONE);
|
SetStretchBltMode(hdc, HALFTONE);
|
||||||
|
|
||||||
// resize color channels
|
// resize color channels
|
||||||
|
@ -170,8 +158,7 @@ static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height)
|
||||||
auto dest = (BYTE*)colorBits;
|
auto dest = (BYTE*)colorBits;
|
||||||
auto src = (const BYTE*)alphaBits;
|
auto src = (const BYTE*)alphaBits;
|
||||||
auto end = src + (width * height * 4);
|
auto end = src + (width * height * 4);
|
||||||
while(src != end)
|
while(src != end) {
|
||||||
{
|
|
||||||
dest[3] = src[0];
|
dest[3] = src[0];
|
||||||
dest += 4;
|
dest += 4;
|
||||||
src += 4;
|
src += 4;
|
||||||
|
@ -199,22 +186,19 @@ static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height)
|
||||||
|
|
||||||
DesktopNotificationController::Toast::Toast(
|
DesktopNotificationController::Toast::Toast(
|
||||||
HWND hWnd, shared_ptr<NotificationData>* data) :
|
HWND hWnd, shared_ptr<NotificationData>* data) :
|
||||||
hwnd_(hWnd), data_(*data)
|
hwnd_(hWnd), data_(*data) {
|
||||||
{
|
|
||||||
HDC hdcScreen = GetDC(NULL);
|
HDC hdcScreen = GetDC(NULL);
|
||||||
hdc_ = CreateCompatibleDC(hdcScreen);
|
hdc_ = CreateCompatibleDC(hdcScreen);
|
||||||
ReleaseDC(NULL, hdcScreen);
|
ReleaseDC(NULL, hdcScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopNotificationController::Toast::~Toast()
|
DesktopNotificationController::Toast::~Toast() {
|
||||||
{
|
|
||||||
DeleteDC(hdc_);
|
DeleteDC(hdc_);
|
||||||
if(bitmap_) DeleteBitmap(bitmap_);
|
if(bitmap_) DeleteBitmap(bitmap_);
|
||||||
if(scaled_image_) DeleteBitmap(scaled_image_);
|
if(scaled_image_) DeleteBitmap(scaled_image_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::Register(HINSTANCE hInstance)
|
void DesktopNotificationController::Toast::Register(HINSTANCE hInstance) {
|
||||||
{
|
|
||||||
WNDCLASSEX wc = { sizeof(wc) };
|
WNDCLASSEX wc = { sizeof(wc) };
|
||||||
wc.lpfnWndProc = &Toast::WndProc;
|
wc.lpfnWndProc = &Toast::WndProc;
|
||||||
wc.lpszClassName = class_name_;
|
wc.lpszClassName = class_name_;
|
||||||
|
@ -226,10 +210,8 @@ void DesktopNotificationController::Toast::Register(HINSTANCE hInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT DesktopNotificationController::Toast::WndProc(
|
LRESULT DesktopNotificationController::Toast::WndProc(
|
||||||
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||||
{
|
switch(message) {
|
||||||
switch(message)
|
|
||||||
{
|
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
auto& cs = reinterpret_cast<const CREATESTRUCT*&>(lParam);
|
auto& cs = reinterpret_cast<const CREATESTRUCT*&>(lParam);
|
||||||
|
@ -249,8 +231,7 @@ LRESULT DesktopNotificationController::Toast::WndProc(
|
||||||
return MA_NOACTIVATE;
|
return MA_NOACTIVATE;
|
||||||
|
|
||||||
case WM_TIMER:
|
case WM_TIMER:
|
||||||
if(wParam == TimerID_AutoDismiss)
|
if(wParam == TimerID_AutoDismiss) {
|
||||||
{
|
|
||||||
Get(hWnd)->AutoDismiss();
|
Get(hWnd)->AutoDismiss();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -272,8 +253,7 @@ LRESULT DesktopNotificationController::Toast::WndProc(
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
{
|
{
|
||||||
auto inst = Get(hWnd);
|
auto inst = Get(hWnd);
|
||||||
if(!inst->is_highlighted_)
|
if(!inst->is_highlighted_) {
|
||||||
{
|
|
||||||
inst->is_highlighted_ = true;
|
inst->is_highlighted_ = true;
|
||||||
|
|
||||||
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hWnd };
|
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hWnd };
|
||||||
|
@ -309,8 +289,7 @@ LRESULT DesktopNotificationController::Toast::WndProc(
|
||||||
case WM_WINDOWPOSCHANGED:
|
case WM_WINDOWPOSCHANGED:
|
||||||
{
|
{
|
||||||
auto& wp = reinterpret_cast<WINDOWPOS*&>(lParam);
|
auto& wp = reinterpret_cast<WINDOWPOS*&>(lParam);
|
||||||
if(wp->flags & SWP_HIDEWINDOW)
|
if(wp->flags & SWP_HIDEWINDOW) {
|
||||||
{
|
|
||||||
if(!IsWindowVisible(hWnd))
|
if(!IsWindowVisible(hWnd))
|
||||||
Get(hWnd)->is_highlighted_ = false;
|
Get(hWnd)->is_highlighted_ = false;
|
||||||
}
|
}
|
||||||
|
@ -322,15 +301,13 @@ LRESULT DesktopNotificationController::Toast::WndProc(
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND DesktopNotificationController::Toast::Create(
|
HWND DesktopNotificationController::Toast::Create(
|
||||||
HINSTANCE hInstance, shared_ptr<NotificationData>& data)
|
HINSTANCE hInstance, shared_ptr<NotificationData>& data) {
|
||||||
{
|
|
||||||
return CreateWindowEx(WS_EX_LAYERED | WS_EX_NOACTIVATE | WS_EX_TOPMOST,
|
return CreateWindowEx(WS_EX_LAYERED | WS_EX_NOACTIVATE | WS_EX_TOPMOST,
|
||||||
class_name_, nullptr, WS_POPUP, 0, 0, 0, 0,
|
class_name_, nullptr, WS_POPUP, 0, 0, 0, 0,
|
||||||
NULL, NULL, hInstance, &data);
|
NULL, NULL, hInstance, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::Draw()
|
void DesktopNotificationController::Toast::Draw() {
|
||||||
{
|
|
||||||
const COLORREF accent = GetAccentColor();
|
const COLORREF accent = GetAccentColor();
|
||||||
|
|
||||||
COLORREF backColor;
|
COLORREF backColor;
|
||||||
|
@ -405,8 +382,7 @@ void DesktopNotificationController::Toast::Draw()
|
||||||
auto textOffsetX = margin_.cx;
|
auto textOffsetX = margin_.cx;
|
||||||
|
|
||||||
BITMAP imageInfo = {};
|
BITMAP imageInfo = {};
|
||||||
if(scaled_image_)
|
if(scaled_image_) {
|
||||||
{
|
|
||||||
GetObject(scaled_image_, sizeof(imageInfo), &imageInfo);
|
GetObject(scaled_image_, sizeof(imageInfo), &imageInfo);
|
||||||
|
|
||||||
textOffsetX += margin_.cx + imageInfo.bmWidth;
|
textOffsetX += margin_.cx + imageInfo.bmWidth;
|
||||||
|
@ -429,8 +405,7 @@ void DesktopNotificationController::Toast::Draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
// image
|
// image
|
||||||
if(scaled_image_)
|
if(scaled_image_) {
|
||||||
{
|
|
||||||
HDC hdcImage = CreateCompatibleDC(NULL);
|
HDC hdcImage = CreateCompatibleDC(NULL);
|
||||||
SelectBitmap(hdcImage, scaled_image_);
|
SelectBitmap(hdcImage, scaled_image_);
|
||||||
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
|
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
|
||||||
|
@ -458,8 +433,7 @@ void DesktopNotificationController::Toast::Draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
// body text
|
// body text
|
||||||
if(!data_->body_text.empty())
|
if(!data_->body_text.empty()) {
|
||||||
{
|
|
||||||
RECT rc = {
|
RECT rc = {
|
||||||
textOffsetX,
|
textOffsetX,
|
||||||
2 * margin_.cy + tmCap.tmAscent,
|
2 * margin_.cy + tmCap.tmAscent,
|
||||||
|
@ -486,34 +460,28 @@ void DesktopNotificationController::Toast::Draw()
|
||||||
is_content_updated_ = true;
|
is_content_updated_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::Invalidate()
|
void DesktopNotificationController::Toast::Invalidate() {
|
||||||
{
|
|
||||||
is_content_updated_ = false;
|
is_content_updated_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DesktopNotificationController::Toast::IsRedrawNeeded() const
|
bool DesktopNotificationController::Toast::IsRedrawNeeded() const {
|
||||||
{
|
|
||||||
return !is_content_updated_;
|
return !is_content_updated_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::UpdateBufferSize()
|
void DesktopNotificationController::Toast::UpdateBufferSize() {
|
||||||
{
|
if(hdc_) {
|
||||||
if(hdc_)
|
|
||||||
{
|
|
||||||
SIZE newSize;
|
SIZE newSize;
|
||||||
{
|
{
|
||||||
TEXTMETRIC tmCap = {};
|
TEXTMETRIC tmCap = {};
|
||||||
HFONT font = data_->controller->GetCaptionFont();
|
HFONT font = data_->controller->GetCaptionFont();
|
||||||
if(font)
|
if(font) {
|
||||||
{
|
|
||||||
SelectFont(hdc_, font);
|
SelectFont(hdc_, font);
|
||||||
if(!GetTextMetrics(hdc_, &tmCap)) return;
|
if(!GetTextMetrics(hdc_, &tmCap)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEXTMETRIC tmBody = {};
|
TEXTMETRIC tmBody = {};
|
||||||
font = data_->controller->GetBodyFont();
|
font = data_->controller->GetBodyFont();
|
||||||
if(font)
|
if(font) {
|
||||||
{
|
|
||||||
SelectFont(hdc_, font);
|
SelectFont(hdc_, font);
|
||||||
if(!GetTextMetrics(hdc_, &tmBody)) return;
|
if(!GetTextMetrics(hdc_, &tmBody)) return;
|
||||||
}
|
}
|
||||||
|
@ -526,28 +494,22 @@ void DesktopNotificationController::Toast::UpdateBufferSize()
|
||||||
if(!data_->body_text.empty())
|
if(!data_->body_text.empty())
|
||||||
newSize.cy += margin_.cy + (3 * tmBody.tmHeight);
|
newSize.cy += margin_.cy + (3 * tmBody.tmHeight);
|
||||||
|
|
||||||
if(data_->image)
|
if(data_->image) {
|
||||||
{
|
|
||||||
BITMAP bm;
|
BITMAP bm;
|
||||||
if(GetObject(data_->image, sizeof(bm), &bm))
|
if(GetObject(data_->image, sizeof(bm), &bm)) {
|
||||||
{
|
|
||||||
// cap the image size
|
// cap the image size
|
||||||
const int maxDimSize = 80;
|
const int maxDimSize = 80;
|
||||||
|
|
||||||
auto width = bm.bmWidth;
|
auto width = bm.bmWidth;
|
||||||
auto height = bm.bmHeight;
|
auto height = bm.bmHeight;
|
||||||
if(width < height)
|
if(width < height) {
|
||||||
{
|
if(height > maxDimSize) {
|
||||||
if(height > maxDimSize)
|
|
||||||
{
|
|
||||||
width = width * maxDimSize / height;
|
width = width * maxDimSize / height;
|
||||||
height = maxDimSize;
|
height = maxDimSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if(width > maxDimSize) {
|
||||||
if(width > maxDimSize)
|
|
||||||
{
|
|
||||||
height = height * maxDimSize / width;
|
height = height * maxDimSize / width;
|
||||||
width = maxDimSize;
|
width = maxDimSize;
|
||||||
}
|
}
|
||||||
|
@ -569,25 +531,20 @@ void DesktopNotificationController::Toast::UpdateBufferSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
if(newSize.cx != this->toast_size_.cx ||
|
if(newSize.cx != this->toast_size_.cx ||
|
||||||
newSize.cy != this->toast_size_.cy)
|
newSize.cy != this->toast_size_.cy) {
|
||||||
{
|
|
||||||
HDC hdcScreen = GetDC(NULL);
|
HDC hdcScreen = GetDC(NULL);
|
||||||
auto newBitmap = CreateCompatibleBitmap(hdcScreen,
|
auto newBitmap = CreateCompatibleBitmap(hdcScreen,
|
||||||
newSize.cx, newSize.cy);
|
newSize.cx, newSize.cy);
|
||||||
ReleaseDC(NULL, hdcScreen);
|
ReleaseDC(NULL, hdcScreen);
|
||||||
|
|
||||||
if(newBitmap)
|
if(newBitmap) {
|
||||||
{
|
if(SelectBitmap(hdc_, newBitmap)) {
|
||||||
if(SelectBitmap(hdc_, newBitmap))
|
|
||||||
{
|
|
||||||
RECT dirty1 = {}, dirty2 = {};
|
RECT dirty1 = {}, dirty2 = {};
|
||||||
if(toast_size_.cx < newSize.cx)
|
if(toast_size_.cx < newSize.cx) {
|
||||||
{
|
|
||||||
dirty1 = { toast_size_.cx, 0,
|
dirty1 = { toast_size_.cx, 0,
|
||||||
newSize.cx, toast_size_.cy };
|
newSize.cx, toast_size_.cy };
|
||||||
}
|
}
|
||||||
if(toast_size_.cy < newSize.cy)
|
if(toast_size_.cy < newSize.cy) {
|
||||||
{
|
|
||||||
dirty2 = { 0, toast_size_.cy,
|
dirty2 = { 0, toast_size_.cy,
|
||||||
newSize.cx, newSize.cy };
|
newSize.cx, newSize.cy };
|
||||||
}
|
}
|
||||||
|
@ -630,24 +587,20 @@ void DesktopNotificationController::Toast::UpdateBufferSize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::UpdateScaledImage(const SIZE& size)
|
void DesktopNotificationController::Toast::UpdateScaledImage(const SIZE& size) {
|
||||||
{
|
|
||||||
BITMAP bm;
|
BITMAP bm;
|
||||||
if(!GetObject(scaled_image_, sizeof(bm), &bm) ||
|
if(!GetObject(scaled_image_, sizeof(bm), &bm) ||
|
||||||
bm.bmWidth != size.cx ||
|
bm.bmWidth != size.cx ||
|
||||||
bm.bmHeight != size.cy)
|
bm.bmHeight != size.cy) {
|
||||||
{
|
|
||||||
if(scaled_image_) DeleteBitmap(scaled_image_);
|
if(scaled_image_) DeleteBitmap(scaled_image_);
|
||||||
scaled_image_ = StretchBitmap(data_->image, size.cx, size.cy);
|
scaled_image_ = StretchBitmap(data_->image, size.cx, size.cy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::UpdateContents()
|
void DesktopNotificationController::Toast::UpdateContents() {
|
||||||
{
|
|
||||||
Draw();
|
Draw();
|
||||||
|
|
||||||
if(IsWindowVisible(hwnd_))
|
if(IsWindowVisible(hwnd_)) {
|
||||||
{
|
|
||||||
RECT rc;
|
RECT rc;
|
||||||
GetWindowRect(hwnd_, &rc);
|
GetWindowRect(hwnd_, &rc);
|
||||||
POINT origin = { 0, 0 };
|
POINT origin = { 0, 0 };
|
||||||
|
@ -657,10 +610,8 @@ void DesktopNotificationController::Toast::UpdateContents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::Dismiss()
|
void DesktopNotificationController::Toast::Dismiss() {
|
||||||
{
|
if(!is_non_interactive_) {
|
||||||
if(!is_non_interactive_)
|
|
||||||
{
|
|
||||||
// Set a flag to prevent further interaction. We don't disable the HWND
|
// Set a flag to prevent further interaction. We don't disable the HWND
|
||||||
// because we still want to receive mouse move messages in order to keep
|
// because we still want to receive mouse move messages in order to keep
|
||||||
// the toast under the cursor and not collapse it while dismissing.
|
// the toast under the cursor and not collapse it while dismissing.
|
||||||
|
@ -670,28 +621,23 @@ void DesktopNotificationController::Toast::Dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::AutoDismiss()
|
void DesktopNotificationController::Toast::AutoDismiss() {
|
||||||
{
|
|
||||||
KillTimer(hwnd_, TimerID_AutoDismiss);
|
KillTimer(hwnd_, TimerID_AutoDismiss);
|
||||||
StartEaseOut();
|
StartEaseOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::CancelDismiss()
|
void DesktopNotificationController::Toast::CancelDismiss() {
|
||||||
{
|
|
||||||
KillTimer(hwnd_, TimerID_AutoDismiss);
|
KillTimer(hwnd_, TimerID_AutoDismiss);
|
||||||
ease_out_active_ = false;
|
ease_out_active_ = false;
|
||||||
ease_out_pos_ = 0;
|
ease_out_pos_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::ScheduleDismissal()
|
void DesktopNotificationController::Toast::ScheduleDismissal() {
|
||||||
{
|
|
||||||
SetTimer(hwnd_, TimerID_AutoDismiss, 4000, nullptr);
|
SetTimer(hwnd_, TimerID_AutoDismiss, 4000, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::ResetContents()
|
void DesktopNotificationController::Toast::ResetContents() {
|
||||||
{
|
if(scaled_image_) {
|
||||||
if(scaled_image_)
|
|
||||||
{
|
|
||||||
DeleteBitmap(scaled_image_);
|
DeleteBitmap(scaled_image_);
|
||||||
scaled_image_ = NULL;
|
scaled_image_ = NULL;
|
||||||
}
|
}
|
||||||
|
@ -699,14 +645,12 @@ void DesktopNotificationController::Toast::ResetContents()
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::PopUp(int y)
|
void DesktopNotificationController::Toast::PopUp(int y) {
|
||||||
{
|
|
||||||
vertical_pos_target_ = vertical_pos_ = y;
|
vertical_pos_target_ = vertical_pos_ = y;
|
||||||
StartEaseIn();
|
StartEaseIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::SetVerticalPosition(int y)
|
void DesktopNotificationController::Toast::SetVerticalPosition(int y) {
|
||||||
{
|
|
||||||
// Don't restart animation if current target is the same
|
// Don't restart animation if current target is the same
|
||||||
if(y == vertical_pos_target_)
|
if(y == vertical_pos_target_)
|
||||||
return;
|
return;
|
||||||
|
@ -722,8 +666,7 @@ void DesktopNotificationController::Toast::SetVerticalPosition(int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
HDWP DesktopNotificationController::Toast::Animate(
|
HDWP DesktopNotificationController::Toast::Animate(
|
||||||
HDWP hdwp, const POINT& origin)
|
HDWP hdwp, const POINT& origin) {
|
||||||
{
|
|
||||||
UpdateBufferSize();
|
UpdateBufferSize();
|
||||||
|
|
||||||
if(IsRedrawNeeded())
|
if(IsRedrawNeeded())
|
||||||
|
@ -764,8 +707,7 @@ HDWP DesktopNotificationController::Toast::Animate(
|
||||||
ulw.pptDst = &pt;
|
ulw.pptDst = &pt;
|
||||||
ulw.psize = &size;
|
ulw.psize = &size;
|
||||||
|
|
||||||
if(ease_in_active_ && easeInPos == 1.0f)
|
if(ease_in_active_ && easeInPos == 1.0f) {
|
||||||
{
|
|
||||||
ease_in_active_ = false;
|
ease_in_active_ = false;
|
||||||
ScheduleDismissal();
|
ScheduleDismissal();
|
||||||
}
|
}
|
||||||
|
@ -773,8 +715,7 @@ HDWP DesktopNotificationController::Toast::Animate(
|
||||||
this->ease_in_pos_ = easeInPos;
|
this->ease_in_pos_ = easeInPos;
|
||||||
this->stack_collapse_pos_ = stackCollapsePos;
|
this->stack_collapse_pos_ = stackCollapsePos;
|
||||||
|
|
||||||
if(easeOutPos != this->ease_out_pos_)
|
if(easeOutPos != this->ease_out_pos_) {
|
||||||
{
|
|
||||||
blend.BlendOp = AC_SRC_OVER;
|
blend.BlendOp = AC_SRC_OVER;
|
||||||
blend.BlendFlags = 0;
|
blend.BlendFlags = 0;
|
||||||
blend.SourceConstantAlpha = (BYTE)(255 * (1.0f - easeOutPos));
|
blend.SourceConstantAlpha = (BYTE)(255 * (1.0f - easeOutPos));
|
||||||
|
@ -785,8 +726,7 @@ HDWP DesktopNotificationController::Toast::Animate(
|
||||||
|
|
||||||
this->ease_out_pos_ = easeOutPos;
|
this->ease_out_pos_ = easeOutPos;
|
||||||
|
|
||||||
if(easeOutPos == 1.0f)
|
if(easeOutPos == 1.0f) {
|
||||||
{
|
|
||||||
ease_out_active_ = false;
|
ease_out_active_ = false;
|
||||||
|
|
||||||
dwpFlags &= ~SWP_SHOWWINDOW;
|
dwpFlags &= ~SWP_SHOWWINDOW;
|
||||||
|
@ -794,8 +734,7 @@ HDWP DesktopNotificationController::Toast::Animate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stackCollapsePos == 1.0f)
|
if(stackCollapsePos == 1.0f) {
|
||||||
{
|
|
||||||
vertical_pos_ = vertical_pos_target_;
|
vertical_pos_ = vertical_pos_target_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,29 +749,25 @@ HDWP DesktopNotificationController::Toast::Animate(
|
||||||
return hdwp;
|
return hdwp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::StartEaseIn()
|
void DesktopNotificationController::Toast::StartEaseIn() {
|
||||||
{
|
|
||||||
_ASSERT(!ease_in_active_);
|
_ASSERT(!ease_in_active_);
|
||||||
ease_in_start_ = GetTickCount();
|
ease_in_start_ = GetTickCount();
|
||||||
ease_in_active_ = true;
|
ease_in_active_ = true;
|
||||||
data_->controller->StartAnimation();
|
data_->controller->StartAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopNotificationController::Toast::StartEaseOut()
|
void DesktopNotificationController::Toast::StartEaseOut() {
|
||||||
{
|
|
||||||
_ASSERT(!ease_out_active_);
|
_ASSERT(!ease_out_active_);
|
||||||
ease_out_start_ = GetTickCount();
|
ease_out_start_ = GetTickCount();
|
||||||
ease_out_active_ = true;
|
ease_out_active_ = true;
|
||||||
data_->controller->StartAnimation();
|
data_->controller->StartAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DesktopNotificationController::Toast::IsStackCollapseActive() const
|
bool DesktopNotificationController::Toast::IsStackCollapseActive() const {
|
||||||
{
|
|
||||||
return (vertical_pos_ != vertical_pos_target_);
|
return (vertical_pos_ != vertical_pos_target_);
|
||||||
}
|
}
|
||||||
|
|
||||||
float DesktopNotificationController::Toast::AnimateEaseIn()
|
float DesktopNotificationController::Toast::AnimateEaseIn() {
|
||||||
{
|
|
||||||
if(!ease_in_active_)
|
if(!ease_in_active_)
|
||||||
return ease_in_pos_;
|
return ease_in_pos_;
|
||||||
|
|
||||||
|
@ -847,8 +782,7 @@ float DesktopNotificationController::Toast::AnimateEaseIn()
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
float DesktopNotificationController::Toast::AnimateEaseOut()
|
float DesktopNotificationController::Toast::AnimateEaseOut() {
|
||||||
{
|
|
||||||
if(!ease_out_active_)
|
if(!ease_out_active_)
|
||||||
return ease_out_pos_;
|
return ease_out_pos_;
|
||||||
|
|
||||||
|
@ -862,8 +796,7 @@ float DesktopNotificationController::Toast::AnimateEaseOut()
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
float DesktopNotificationController::Toast::AnimateStackCollapse()
|
float DesktopNotificationController::Toast::AnimateStackCollapse() {
|
||||||
{
|
|
||||||
if(!IsStackCollapseActive())
|
if(!IsStackCollapseActive())
|
||||||
return stack_collapse_pos_;
|
return stack_collapse_pos_;
|
||||||
|
|
||||||
|
|
|
@ -3,22 +3,19 @@
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
class DesktopNotificationController::Toast
|
class DesktopNotificationController::Toast {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static void Register(HINSTANCE hInstance);
|
static void Register(HINSTANCE hInstance);
|
||||||
static HWND Create(HINSTANCE hInstance,
|
static HWND Create(HINSTANCE hInstance,
|
||||||
std::shared_ptr<NotificationData>& data);
|
std::shared_ptr<NotificationData>& data);
|
||||||
static Toast* Get(HWND hWnd)
|
static Toast* Get(HWND hWnd) {
|
||||||
{
|
|
||||||
return reinterpret_cast<Toast*>(GetWindowLongPtr(hWnd, 0));
|
return reinterpret_cast<Toast*>(GetWindowLongPtr(hWnd, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
|
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
|
||||||
WPARAM wParam, LPARAM lParam);
|
WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
const std::shared_ptr<NotificationData>& GetNotification() const
|
const std::shared_ptr<NotificationData>& GetNotification() const {
|
||||||
{
|
|
||||||
return data_;
|
return data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,21 +25,17 @@ public:
|
||||||
|
|
||||||
void PopUp(int y);
|
void PopUp(int y);
|
||||||
void SetVerticalPosition(int y);
|
void SetVerticalPosition(int y);
|
||||||
int GetVerticalPosition() const
|
int GetVerticalPosition() const {
|
||||||
{
|
|
||||||
return vertical_pos_target_;
|
return vertical_pos_target_;
|
||||||
}
|
}
|
||||||
int GetHeight() const
|
int GetHeight() const {
|
||||||
{
|
|
||||||
return toast_size_.cy;
|
return toast_size_.cy;
|
||||||
}
|
}
|
||||||
HDWP Animate(HDWP hdwp, const POINT& origin);
|
HDWP Animate(HDWP hdwp, const POINT& origin);
|
||||||
bool IsAnimationActive() const
|
bool IsAnimationActive() const {
|
||||||
{
|
|
||||||
return ease_in_active_ || ease_out_active_ || IsStackCollapseActive();
|
return ease_in_active_ || ease_out_active_ || IsStackCollapseActive();
|
||||||
}
|
}
|
||||||
bool IsHighlighted() const
|
bool IsHighlighted() const {
|
||||||
{
|
|
||||||
_ASSERT(!(is_highlighted_ && !IsWindowVisible(hwnd_)));
|
_ASSERT(!(is_highlighted_ && !IsWindowVisible(hwnd_)));
|
||||||
return is_highlighted_;
|
return is_highlighted_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,14 @@ namespace brightray {
|
||||||
void Win32Notification::Show(
|
void Win32Notification::Show(
|
||||||
const base::string16& title, const base::string16& msg,
|
const base::string16& title, const base::string16& msg,
|
||||||
const std::string& tag, const GURL& icon_url,
|
const std::string& tag, const GURL& icon_url,
|
||||||
const SkBitmap& icon, const bool silent)
|
const SkBitmap& icon, const bool silent) {
|
||||||
{
|
|
||||||
auto presenter = static_cast<NotificationPresenterWin7*>(this->presenter());
|
auto presenter = static_cast<NotificationPresenterWin7*>(this->presenter());
|
||||||
if(!presenter) return;
|
if(!presenter) return;
|
||||||
|
|
||||||
HBITMAP image = NULL;
|
HBITMAP image = NULL;
|
||||||
|
|
||||||
if(!icon.drawsNothing())
|
if(!icon.drawsNothing()) {
|
||||||
{
|
if(icon.colorType() == kBGRA_8888_SkColorType) {
|
||||||
if(icon.colorType() == kBGRA_8888_SkColorType)
|
|
||||||
{
|
|
||||||
icon.lockPixels();
|
icon.lockPixels();
|
||||||
|
|
||||||
BITMAPINFOHEADER bmi = { sizeof(BITMAPINFOHEADER) };
|
BITMAPINFOHEADER bmi = { sizeof(BITMAPINFOHEADER) };
|
||||||
|
@ -40,14 +37,12 @@ void Win32Notification::Show(
|
||||||
Win32Notification* existing = nullptr;
|
Win32Notification* existing = nullptr;
|
||||||
if(!tag.empty()) existing = presenter->GetNotificationObjectByTag(tag);
|
if(!tag.empty()) existing = presenter->GetNotificationObjectByTag(tag);
|
||||||
|
|
||||||
if(existing)
|
if(existing) {
|
||||||
{
|
|
||||||
existing->tag_.clear();
|
existing->tag_.clear();
|
||||||
this->notification_ref_ = std::move(existing->notification_ref_);
|
this->notification_ref_ = std::move(existing->notification_ref_);
|
||||||
this->notification_ref_.Set(title, msg, image);
|
this->notification_ref_.Set(title, msg, image);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
this->notification_ref_ = presenter->AddNotification(title, msg, image);
|
this->notification_ref_ = presenter->AddNotification(title, msg, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,8 +51,7 @@ void Win32Notification::Show(
|
||||||
if(image) DeleteObject(image);
|
if(image) DeleteObject(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win32Notification::Dismiss()
|
void Win32Notification::Dismiss() {
|
||||||
{
|
|
||||||
notification_ref_.Close();
|
notification_ref_.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,26 +4,22 @@
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
class Win32Notification : public brightray::Notification
|
class Win32Notification : public brightray::Notification {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Win32Notification(NotificationDelegate* delegate,
|
Win32Notification(NotificationDelegate* delegate,
|
||||||
NotificationPresenterWin7* presenter) :
|
NotificationPresenterWin7* presenter) :
|
||||||
Notification(delegate, presenter)
|
Notification(delegate, presenter) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
void Show(const base::string16& title, const base::string16& msg,
|
void Show(const base::string16& title, const base::string16& msg,
|
||||||
const std::string& tag, const GURL& icon_url,
|
const std::string& tag, const GURL& icon_url,
|
||||||
const SkBitmap& icon, const bool silent) override;
|
const SkBitmap& icon, const bool silent) override;
|
||||||
void Dismiss() override;
|
void Dismiss() override;
|
||||||
|
|
||||||
const DesktopNotificationController::Notification& GetRef() const
|
const DesktopNotificationController::Notification& GetRef() const {
|
||||||
{
|
|
||||||
return notification_ref_;
|
return notification_ref_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& GetTag() const
|
const std::string& GetTag() const {
|
||||||
{
|
|
||||||
return tag_;
|
return tag_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue