Address cpplint issue "{ should almost always be at the end of the previous line [whitespace/braces] [4]"

This commit is contained in:
Ales Pergl 2017-04-03 12:11:39 +02:00
parent 63eeb96e71
commit 29f3332276
9 changed files with 152 additions and 304 deletions

View file

@ -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();
} }

View file

@ -8,8 +8,7 @@ class Win32Notification;
class NotificationPresenterWin7 : class NotificationPresenterWin7 :
public NotificationPresenter, public NotificationPresenter,
public DesktopNotificationController public DesktopNotificationController {
{
public: public:
NotificationPresenterWin7() = default; NotificationPresenterWin7() = default;

View file

@ -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;

View file

@ -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;
} }

View file

@ -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);

View file

@ -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_;

View file

@ -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_;
} }

View file

@ -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();
} }

View file

@ -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_;
} }