Changed member variable naming style to snake case

This commit is contained in:
Ales Pergl 2017-03-17 14:41:22 +01:00
parent 0fa6c82b3f
commit 392d606848
7 changed files with 251 additions and 251 deletions

View file

@ -8,7 +8,7 @@ struct NotificationData
DesktopNotificationController* controller = nullptr;
std::wstring caption;
std::wstring bodyText;
std::wstring body_text;
HBITMAP image = NULL;
@ -31,7 +31,7 @@ inline T ScaleForDpi(T value, unsigned dpi)
struct ScreenMetrics
{
UINT dpiX, dpiY;
UINT dpi_x, dpi_y;
ScreenMetrics()
{
@ -40,18 +40,18 @@ struct ScreenMetrics
if(GetDpiForMonitor)
{
auto monitor = MonitorFromPoint({}, MONITOR_DEFAULTTOPRIMARY);
if(GetDpiForMonitor(monitor, 0, &dpiX, &dpiY) == S_OK)
if(GetDpiForMonitor(monitor, 0, &dpi_x, &dpi_y) == S_OK)
return;
}
HDC hdc = GetDC(NULL);
dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(NULL, hdc);
}
template<typename T> T X(T value) const { return ScaleForDpi(value, dpiX); }
template<typename T> T Y(T value) const { return ScaleForDpi(value, dpiY); }
template<typename T> T X(T value) const { return ScaleForDpi(value, dpi_x); }
template<typename T> T Y(T value) const { return ScaleForDpi(value, dpi_y); }
};
}

View file

@ -53,7 +53,7 @@ HINSTANCE DesktopNotificationController::RegisterWndClasses()
WNDCLASSEX wc = { sizeof(wc) };
wc.lpfnWndProc = &WndProc;
wc.lpszClassName = className;
wc.lpszClassName = class_name_;
wc.cbWndExtra = sizeof(DesktopNotificationController*);
wc.hInstance = module;
@ -66,13 +66,13 @@ HINSTANCE DesktopNotificationController::RegisterWndClasses()
DesktopNotificationController::DesktopNotificationController(unsigned maximumToasts)
{
instances.reserve(maximumToasts);
instances_.reserve(maximumToasts);
}
DesktopNotificationController::~DesktopNotificationController()
{
for(auto&& inst : instances) DestroyToast(inst);
if(hwndController) DestroyWindow(hwndController);
for(auto&& inst : instances_) DestroyToast(inst);
if(hwnd_controller_) DestroyWindow(hwnd_controller_);
ClearAssets();
}
@ -115,33 +115,33 @@ LRESULT CALLBACK DesktopNotificationController::WndProc(HWND hWnd, UINT message,
void DesktopNotificationController::StartAnimation()
{
_ASSERT(hwndController);
_ASSERT(hwnd_controller_);
if(!isAnimating && hwndController)
if(!is_animating_ && hwnd_controller_)
{
// 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 to get at least 60
SetTimer(hwndController, TimerID_Animate, 15, nullptr);
isAnimating = true;
SetTimer(hwnd_controller_, TimerID_Animate, 15, nullptr);
is_animating_ = true;
}
}
HFONT DesktopNotificationController::GetCaptionFont()
{
InitializeFonts();
return captionFont;
return caption_font_;
}
HFONT DesktopNotificationController::GetBodyFont()
{
InitializeFonts();
return bodyFont;
return body_font_;
}
void DesktopNotificationController::InitializeFonts()
{
if(!bodyFont)
if(!body_font_)
{
NONCLIENTMETRICS metrics = { sizeof(metrics) };
if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrics, 0))
@ -153,19 +153,19 @@ void DesktopNotificationController::InitializeFonts()
ReleaseDC(NULL, hdc);
metrics.lfMessageFont.lfHeight = (LONG)ScaleForDpi(baseHeight * 1.1f, dpiY);
bodyFont = CreateFontIndirect(&metrics.lfMessageFont);
body_font_ = CreateFontIndirect(&metrics.lfMessageFont);
if(captionFont) DeleteFont(captionFont);
if(caption_font_) DeleteFont(caption_font_);
metrics.lfMessageFont.lfHeight = (LONG)ScaleForDpi(baseHeight * 1.4f, dpiY);
captionFont = CreateFontIndirect(&metrics.lfMessageFont);
caption_font_ = CreateFontIndirect(&metrics.lfMessageFont);
}
}
}
void DesktopNotificationController::ClearAssets()
{
if(captionFont) { DeleteFont(captionFont); captionFont = NULL; }
if(bodyFont) { DeleteFont(bodyFont); bodyFont = NULL; }
if(caption_font_) { DeleteFont(caption_font_); caption_font_ = NULL; }
if(body_font_) { DeleteFont(body_font_); body_font_ = NULL; }
}
void DesktopNotificationController::AnimateAll()
@ -176,17 +176,17 @@ void DesktopNotificationController::AnimateAll()
bool keepAnimating = false;
if(!instances.empty())
if(!instances_.empty())
{
RECT workArea;
if(SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0))
{
ScreenMetrics metrics;
POINT origin = { workArea.right,
workArea.bottom - metrics.Y(toastMargin<int>) };
workArea.bottom - metrics.Y(toast_margin_<int>) };
auto hdwp = BeginDeferWindowPos((int)instances.size());
for(auto&& inst : instances)
auto hdwp = BeginDeferWindowPos((int)instances_.size());
for(auto&& inst : instances_)
{
if(!inst.hwnd) continue;
@ -201,14 +201,14 @@ void DesktopNotificationController::AnimateAll()
if(!keepAnimating)
{
_ASSERT(hwndController);
if(hwndController) KillTimer(hwndController, TimerID_Animate);
isAnimating = false;
_ASSERT(hwnd_controller_);
if(hwnd_controller_) KillTimer(hwnd_controller_, TimerID_Animate);
is_animating_ = false;
}
// Purge dismissed notifications and collapse the stack between
// items which are highlighted
if(!instances.empty())
if(!instances_.empty())
{
auto isAlive = [](ToastInstance& inst) {
return inst.hwnd && IsWindowVisible(inst.hwnd);
@ -218,10 +218,10 @@ void DesktopNotificationController::AnimateAll()
return inst.hwnd && Toast::Get(inst.hwnd)->IsHighlighted();
};
for(auto it = instances.begin();; ++it)
for(auto it = instances_.begin();; ++it)
{
// find next highlighted item
auto it2 = find_if(it, instances.end(), isHighlighted);
auto it2 = find_if(it, instances_.end(), isHighlighted);
// collapse the stack in front of the highlighted item
it = stable_partition(it, it2, isAlive);
@ -229,9 +229,9 @@ void DesktopNotificationController::AnimateAll()
// purge the dead items
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;
}
@ -240,13 +240,13 @@ void DesktopNotificationController::AnimateAll()
}
// Set new toast positions
if(!instances.empty())
if(!instances_.empty())
{
ScreenMetrics metrics;
auto margin = metrics.Y(toastMargin<int>);
auto margin = metrics.Y(toast_margin_<int>);
int targetPos = 0;
for(auto&& inst : instances)
for(auto&& inst : instances_)
{
if(inst.hwnd)
{
@ -271,11 +271,11 @@ DesktopNotificationController::Notification DesktopNotificationController::AddNo
NotificationLink data(this);
data->caption = move(caption);
data->bodyText = move(bodyText);
data->body_text = move(bodyText);
data->image = CopyBitmap(image);
// Enqueue new notification
Notification ret = *queue.insert(queue.end(), move(data));
Notification ret = *queue_.insert(queue_.end(), move(data));
CheckQueue();
return ret;
}
@ -283,16 +283,16 @@ DesktopNotificationController::Notification DesktopNotificationController::AddNo
void DesktopNotificationController::CloseNotification(Notification& notification)
{
// Remove it from the queue
auto it = find(queue.begin(), queue.end(), notification.data);
if(it != queue.end())
auto it = find(queue_.begin(), queue_.end(), notification.data_);
if(it != queue_.end())
{
queue.erase(it);
queue_.erase(it);
this->OnNotificationClosed(notification);
return;
}
// Dismiss active toast
auto hwnd = GetToast(notification.data.get());
auto hwnd = GetToast(notification.data_.get());
if(hwnd)
{
auto toast = Toast::Get(hwnd);
@ -302,10 +302,10 @@ void DesktopNotificationController::CloseNotification(Notification& notification
void DesktopNotificationController::CheckQueue()
{
while(instances.size() < instances.capacity() && !queue.empty())
while(instances_.size() < instances_.capacity() && !queue_.empty())
{
CreateToast(move(queue.front()));
queue.pop_front();
CreateToast(move(queue_.front()));
queue_.pop_front();
}
}
@ -316,22 +316,22 @@ void DesktopNotificationController::CreateToast(NotificationLink&& data)
if(hwnd)
{
int toastPos = 0;
if(!instances.empty())
if(!instances_.empty())
{
auto& item = instances.back();
auto& item = instances_.back();
_ASSERT(item.hwnd);
ScreenMetrics scr;
auto toast = Toast::Get(item.hwnd);
toastPos = toast->GetVerticalPosition() + toast->GetHeight() + scr.Y(toastMargin<int>);
toastPos = toast->GetVerticalPosition() + toast->GetHeight() + scr.Y(toast_margin_<int>);
}
instances.push_back({ hwnd, move(data) });
instances_.push_back({ hwnd, move(data) });
if(!hwndController)
if(!hwnd_controller_)
{
// NOTE: We cannot use a message-only window because we need to receive system notifications
hwndController = CreateWindow(className, nullptr, 0, 0, 0, 0, 0, NULL, NULL, hInstance, this);
hwnd_controller_ = CreateWindow(class_name_, nullptr, 0, 0, 0, 0, 0, NULL, NULL, hInstance, this);
}
auto toast = Toast::Get(hwnd);
@ -341,12 +341,12 @@ void DesktopNotificationController::CreateToast(NotificationLink&& data)
HWND DesktopNotificationController::GetToast(const NotificationData* data) const
{
auto it = find_if(instances.cbegin(), instances.cend(), [data](auto&& inst) {
auto it = find_if(instances_.cbegin(), instances_.cend(), [data](auto&& inst) {
auto toast = Toast::Get(inst.hwnd);
return data == toast->GetNotification().get();
});
return (it != instances.cend()) ? it->hwnd : NULL;
return (it != instances_.cend()) ? it->hwnd : NULL;
}
void DesktopNotificationController::DestroyToast(ToastInstance& inst)
@ -365,41 +365,41 @@ void DesktopNotificationController::DestroyToast(ToastInstance& inst)
DesktopNotificationController::Notification::Notification(const shared_ptr<NotificationData>& data) :
data(data)
data_(data)
{
_ASSERT(data != nullptr);
}
bool DesktopNotificationController::Notification::operator==(const Notification& other) const
{
return data == other.data;
return data_ == other.data_;
}
void DesktopNotificationController::Notification::Close()
{
// No business calling this when not pointing to a valid instance
_ASSERT(data);
_ASSERT(data_);
if(data->controller)
data->controller->CloseNotification(*this);
if(data_->controller)
data_->controller->CloseNotification(*this);
}
void DesktopNotificationController::Notification::Set(std::wstring caption, std::wstring bodyText, HBITMAP image)
{
// No business calling this when not pointing to a valid instance
_ASSERT(data);
_ASSERT(data_);
// Do nothing when the notification has been closed
if(!data->controller)
if(!data_->controller)
return;
if(data->image) DeleteBitmap(data->image);
if(data_->image) DeleteBitmap(data_->image);
data->caption = move(caption);
data->bodyText = move(bodyText);
data->image = CopyBitmap(image);
data_->caption = move(caption);
data_->body_text = move(bodyText);
data_->image = CopyBitmap(image);
auto hwnd = data->controller->GetToast(data.get());
auto hwnd = data_->controller->GetToast(data_.get());
if(hwnd)
{
auto toast = Toast::Get(hwnd);
@ -407,7 +407,7 @@ void DesktopNotificationController::Notification::Set(std::wstring caption, std:
}
// Change of contents can affect size and position of all toasts
data->controller->StartAnimation();
data_->controller->StartAnimation();
}

View file

@ -37,7 +37,7 @@ private:
};
template<typename T>
static constexpr T toastMargin = 20;
static constexpr T toast_margin_ = 20;
// Wrapper around `NotificationData` which makes sure that
// the `controller` member is cleared when the controller object
@ -75,12 +75,12 @@ private:
void DestroyToast(ToastInstance& inst);
private:
static constexpr const TCHAR className[] = TEXT("DesktopNotificationController");
HWND hwndController = NULL;
HFONT captionFont = NULL, bodyFont = NULL;
std::vector<ToastInstance> instances;
std::deque<NotificationLink> queue;
bool isAnimating = false;
static constexpr const TCHAR class_name_[] = TEXT("DesktopNotificationController");
HWND hwnd_controller_ = NULL;
HFONT caption_font_ = NULL, body_font_ = NULL;
std::vector<ToastInstance> instances_;
std::deque<NotificationLink> queue_;
bool is_animating_ = false;
};
class DesktopNotificationController::Notification
@ -95,7 +95,7 @@ public:
void Set(std::wstring caption, std::wstring bodyText, HBITMAP image);
private:
std::shared_ptr<NotificationData> data;
std::shared_ptr<NotificationData> data_;
friend class DesktopNotificationController;
};

View file

@ -167,25 +167,25 @@ static HBITMAP StretchBitmap(HBITMAP bitmap, unsigned width, unsigned height)
}
DesktopNotificationController::Toast::Toast(HWND hWnd, shared_ptr<NotificationData>* data) :
hWnd(hWnd), data(*data)
hwnd_(hWnd), data_(*data)
{
HDC hdcScreen = GetDC(NULL);
hdc = CreateCompatibleDC(hdcScreen);
hdc_ = CreateCompatibleDC(hdcScreen);
ReleaseDC(NULL, hdcScreen);
}
DesktopNotificationController::Toast::~Toast()
{
DeleteDC(hdc);
if(bitmap) DeleteBitmap(bitmap);
if(scaledImage) DeleteBitmap(scaledImage);
DeleteDC(hdc_);
if(bitmap_) DeleteBitmap(bitmap_);
if(scaled_image_) DeleteBitmap(scaled_image_);
}
void DesktopNotificationController::Toast::Register(HINSTANCE hInstance)
{
WNDCLASSEX wc = { sizeof(wc) };
wc.lpfnWndProc = &Toast::WndProc;
wc.lpszClassName = className;
wc.lpszClassName = class_name_;
wc.cbWndExtra = sizeof(Toast*);
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
@ -226,29 +226,29 @@ LRESULT DesktopNotificationController::Toast::WndProc(HWND hWnd, UINT message, W
inst->Dismiss();
Notification notification(inst->data);
if(inst->isCloseHot)
inst->data->controller->OnNotificationDismissed(notification);
Notification notification(inst->data_);
if(inst->is_close_hot_)
inst->data_->controller->OnNotificationDismissed(notification);
else
inst->data->controller->OnNotificationClicked(notification);
inst->data_->controller->OnNotificationClicked(notification);
}
return 0;
case WM_MOUSEMOVE:
{
auto inst = Get(hWnd);
if(!inst->isHighlighted)
if(!inst->is_highlighted_)
{
inst->isHighlighted = true;
inst->is_highlighted_ = true;
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hWnd };
TrackMouseEvent(&tme);
}
POINT cursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
inst->isCloseHot = (PtInRect(&inst->closeButtonRect, cursor) != FALSE);
inst->is_close_hot_ = (PtInRect(&inst->close_button_rect_, cursor) != FALSE);
if(!inst->isNonInteractive)
if(!inst->is_non_interactive_)
inst->CancelDismiss();
inst->UpdateContents();
@ -258,15 +258,15 @@ LRESULT DesktopNotificationController::Toast::WndProc(HWND hWnd, UINT message, W
case WM_MOUSELEAVE:
{
auto inst = Get(hWnd);
inst->isHighlighted = false;
inst->isCloseHot = false;
inst->is_highlighted_ = false;
inst->is_close_hot_ = false;
inst->UpdateContents();
if(!inst->easeOutActive && inst->easeInPos == 1.0f)
if(!inst->ease_out_active_ && inst->ease_in_pos_ == 1.0f)
inst->ScheduleDismissal();
// Make sure stack collapse happens if needed
inst->data->controller->StartAnimation();
inst->data_->controller->StartAnimation();
}
return 0;
@ -276,7 +276,7 @@ LRESULT DesktopNotificationController::Toast::WndProc(HWND hWnd, UINT message, W
if(wp->flags & SWP_HIDEWINDOW)
{
if(!IsWindowVisible(hWnd))
Get(hWnd)->isHighlighted = false;
Get(hWnd)->is_highlighted_ = false;
}
}
break;
@ -287,7 +287,7 @@ LRESULT DesktopNotificationController::Toast::WndProc(HWND hWnd, UINT message, W
HWND DesktopNotificationController::Toast::Create(HINSTANCE hInstance, shared_ptr<NotificationData>& data)
{
return CreateWindowEx(WS_EX_LAYERED | WS_EX_NOACTIVATE | WS_EX_TOPMOST, className, nullptr, WS_POPUP, 0, 0, 0, 0, NULL, NULL, hInstance, &data);
return CreateWindowEx(WS_EX_LAYERED | WS_EX_NOACTIVATE | WS_EX_TOPMOST, class_name_, nullptr, WS_POPUP, 0, 0, 0, 0, NULL, NULL, hInstance, &data);
}
void DesktopNotificationController::Toast::Draw()
@ -299,7 +299,7 @@ void DesktopNotificationController::Toast::Draw()
// base background color is 2/3 of accent
// highlighted adds a bit of intensity to every channel
int h = isHighlighted ? (0xff / 20) : 0;
int h = is_highlighted_ ? (0xff / 20) : 0;
backColor = RGB(min(0xff, (GetRValue(accent) * 2 / 3) + h),
min(0xff, (GetGValue(accent) * 2 / 3) + h),
@ -347,55 +347,55 @@ void DesktopNotificationController::Toast::Draw()
{
auto brush = CreateSolidBrush(backColor);
RECT rc = { 0, 0, toastSize.cx, toastSize.cy };
FillRect(hdc, &rc, brush);
RECT rc = { 0, 0, toast_size_.cx, toast_size_.cy };
FillRect(hdc_, &rc, brush);
DeleteBrush(brush);
}
SetBkMode(hdc, TRANSPARENT);
SetBkMode(hdc_, TRANSPARENT);
const auto close = L'\x2715';
auto captionFont = data->controller->GetCaptionFont();
auto bodyFont = data->controller->GetBodyFont();
auto captionFont = data_->controller->GetCaptionFont();
auto bodyFont = data_->controller->GetBodyFont();
TEXTMETRIC tmCap;
SelectFont(hdc, captionFont);
GetTextMetrics(hdc, &tmCap);
SelectFont(hdc_, captionFont);
GetTextMetrics(hdc_, &tmCap);
auto textOffsetX = margin.cx;
auto textOffsetX = margin_.cx;
BITMAP imageInfo = {};
if(scaledImage)
if(scaled_image_)
{
GetObject(scaledImage, sizeof(imageInfo), &imageInfo);
GetObject(scaled_image_, sizeof(imageInfo), &imageInfo);
textOffsetX += margin.cx + imageInfo.bmWidth;
textOffsetX += margin_.cx + imageInfo.bmWidth;
}
// calculate close button rect
POINT closePos;
{
SIZE extent = {};
GetTextExtentPoint32W(hdc, &close, 1, &extent);
GetTextExtentPoint32W(hdc_, &close, 1, &extent);
closeButtonRect.right = toastSize.cx;
closeButtonRect.top = 0;
close_button_rect_.right = toast_size_.cx;
close_button_rect_.top = 0;
closePos.x = closeButtonRect.right - margin.cy - extent.cx;
closePos.y = closeButtonRect.top + margin.cy;
closePos.x = close_button_rect_.right - margin_.cy - extent.cx;
closePos.y = close_button_rect_.top + margin_.cy;
closeButtonRect.left = closePos.x - margin.cy;
closeButtonRect.bottom = closePos.y + extent.cy + margin.cy;
close_button_rect_.left = closePos.x - margin_.cy;
close_button_rect_.bottom = closePos.y + extent.cy + margin_.cy;
}
// image
if(scaledImage)
if(scaled_image_)
{
HDC hdcImage = CreateCompatibleDC(NULL);
SelectBitmap(hdcImage, scaledImage);
SelectBitmap(hdcImage, scaled_image_);
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
AlphaBlend(hdc, margin.cx, margin.cy, imageInfo.bmWidth, imageInfo.bmHeight, hdcImage, 0, 0, imageInfo.bmWidth, imageInfo.bmHeight, blend);
AlphaBlend(hdc_, margin_.cx, margin_.cy, imageInfo.bmWidth, imageInfo.bmHeight, hdcImage, 0, 0, imageInfo.bmWidth, imageInfo.bmHeight, blend);
DeleteDC(hdcImage);
}
@ -403,85 +403,85 @@ void DesktopNotificationController::Toast::Draw()
{
RECT rc = {
textOffsetX,
margin.cy,
closeButtonRect.left,
toastSize.cy
margin_.cy,
close_button_rect_.left,
toast_size_.cy
};
SelectFont(hdc, captionFont);
SetTextColor(hdc, foreColor);
DrawText(hdc, data->caption.data(), (UINT)data->caption.length(), &rc, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX);
SelectFont(hdc_, captionFont);
SetTextColor(hdc_, foreColor);
DrawText(hdc_, data_->caption.data(), (UINT)data_->caption.length(), &rc, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX);
}
// body text
if(!data->bodyText.empty())
if(!data_->body_text.empty())
{
RECT rc = {
textOffsetX,
2 * margin.cy + tmCap.tmAscent,
toastSize.cx - margin.cx,
toastSize.cy - margin.cy
2 * margin_.cy + tmCap.tmAscent,
toast_size_.cx - margin_.cx,
toast_size_.cy - margin_.cy
};
SelectFont(hdc, bodyFont);
SetTextColor(hdc, dimmedColor);
DrawText(hdc, data->bodyText.data(), (UINT)data->bodyText.length(), &rc, DT_LEFT | DT_WORDBREAK | DT_NOPREFIX | DT_END_ELLIPSIS | DT_EDITCONTROL);
SelectFont(hdc_, bodyFont);
SetTextColor(hdc_, dimmedColor);
DrawText(hdc_, data_->body_text.data(), (UINT)data_->body_text.length(), &rc, DT_LEFT | DT_WORDBREAK | DT_NOPREFIX | DT_END_ELLIPSIS | DT_EDITCONTROL);
}
// close button
{
SelectFont(hdc, captionFont);
SetTextColor(hdc, isCloseHot ? foreColor : dimmedColor);
ExtTextOut(hdc, closePos.x, closePos.y, 0, nullptr, &close, 1, nullptr);
SelectFont(hdc_, captionFont);
SetTextColor(hdc_, is_close_hot_ ? foreColor : dimmedColor);
ExtTextOut(hdc_, closePos.x, closePos.y, 0, nullptr, &close, 1, nullptr);
}
isContentUpdated = true;
is_content_updated_ = true;
}
void DesktopNotificationController::Toast::Invalidate()
{
isContentUpdated = false;
is_content_updated_ = false;
}
bool DesktopNotificationController::Toast::IsRedrawNeeded() const
{
return !isContentUpdated;
return !is_content_updated_;
}
void DesktopNotificationController::Toast::UpdateBufferSize()
{
if(hdc)
if(hdc_)
{
SIZE newSize;
{
TEXTMETRIC tmCap = {};
HFONT font = data->controller->GetCaptionFont();
HFONT font = data_->controller->GetCaptionFont();
if(font)
{
SelectFont(hdc, font);
if(!GetTextMetrics(hdc, &tmCap)) return;
SelectFont(hdc_, font);
if(!GetTextMetrics(hdc_, &tmCap)) return;
}
TEXTMETRIC tmBody = {};
font = data->controller->GetBodyFont();
font = data_->controller->GetBodyFont();
if(font)
{
SelectFont(hdc, font);
if(!GetTextMetrics(hdc, &tmBody)) return;
SelectFont(hdc_, font);
if(!GetTextMetrics(hdc_, &tmBody)) return;
}
this->margin = { tmCap.tmAveCharWidth * 2, tmCap.tmAscent / 2 };
this->margin_ = { tmCap.tmAveCharWidth * 2, tmCap.tmAscent / 2 };
newSize.cx = margin.cx + (32 * tmCap.tmAveCharWidth) + margin.cx;
newSize.cy = margin.cy + (tmCap.tmHeight) + margin.cy;
newSize.cx = margin_.cx + (32 * tmCap.tmAveCharWidth) + margin_.cx;
newSize.cy = margin_.cy + (tmCap.tmHeight) + margin_.cy;
if(!data->bodyText.empty())
newSize.cy += margin.cy + (3 * tmBody.tmHeight);
if(!data_->body_text.empty())
newSize.cy += margin_.cy + (3 * tmBody.tmHeight);
if(data->image)
if(data_->image)
{
BITMAP bm;
if(GetObject(data->image, sizeof(bm), &bm))
if(GetObject(data_->image, sizeof(bm), &bm))
{
// cap the image size
const int maxDimSize = 80;
@ -508,9 +508,9 @@ void DesktopNotificationController::Toast::UpdateBufferSize()
ScreenMetrics scr;
SIZE imageDrawSize = { scr.X(width), scr.Y(height) };
newSize.cx += imageDrawSize.cx + margin.cx;
newSize.cx += imageDrawSize.cx + margin_.cx;
auto heightWithImage = margin.cy + (imageDrawSize.cy) + margin.cy;
auto heightWithImage = margin_.cy + (imageDrawSize.cy) + margin_.cy;
if(newSize.cy < heightWithImage) newSize.cy = heightWithImage;
UpdateScaledImage(imageDrawSize);
@ -518,7 +518,7 @@ void DesktopNotificationController::Toast::UpdateBufferSize()
}
}
if(newSize.cx != this->toastSize.cx || newSize.cy != this->toastSize.cy)
if(newSize.cx != this->toast_size_.cx || newSize.cy != this->toast_size_.cy)
{
HDC hdcScreen = GetDC(NULL);
auto newBitmap = CreateCompatibleBitmap(hdcScreen, newSize.cx, newSize.cy);
@ -526,15 +526,15 @@ void DesktopNotificationController::Toast::UpdateBufferSize()
if(newBitmap)
{
if(SelectBitmap(hdc, newBitmap))
if(SelectBitmap(hdc_, newBitmap))
{
RECT dirty1 = {}, dirty2 = {};
if(toastSize.cx < newSize.cx) dirty1 = { toastSize.cx, 0, newSize.cx, toastSize.cy };
if(toastSize.cy < newSize.cy) dirty2 = { 0, toastSize.cy, newSize.cx, newSize.cy };
if(toast_size_.cx < newSize.cx) dirty1 = { toast_size_.cx, 0, newSize.cx, toast_size_.cy };
if(toast_size_.cy < newSize.cy) dirty2 = { 0, toast_size_.cy, newSize.cx, newSize.cy };
if(this->bitmap) DeleteBitmap(this->bitmap);
this->bitmap = newBitmap;
this->toastSize = newSize;
if(this->bitmap_) DeleteBitmap(this->bitmap_);
this->bitmap_ = newBitmap;
this->toast_size_ = newSize;
Invalidate();
@ -547,16 +547,16 @@ void DesktopNotificationController::Toast::UpdateBufferSize()
ulw.cbSize = sizeof(ulw);
ulw.hdcDst = NULL;
ulw.pptDst = nullptr;
ulw.psize = &toastSize;
ulw.hdcSrc = hdc;
ulw.psize = &toast_size_;
ulw.hdcSrc = hdc_;
ulw.pptSrc = &origin;
ulw.crKey = 0;
ulw.pblend = nullptr;
ulw.dwFlags = 0;
ulw.prcDirty = &dirty1;
auto b1 = UpdateLayeredWindowIndirect(hWnd, &ulw);
auto b1 = UpdateLayeredWindowIndirect(hwnd_, &ulw);
ulw.prcDirty = &dirty2;
auto b2 = UpdateLayeredWindowIndirect(hWnd, &ulw);
auto b2 = UpdateLayeredWindowIndirect(hwnd_, &ulw);
_ASSERT(b1 && b2);
}
@ -572,12 +572,12 @@ void DesktopNotificationController::Toast::UpdateBufferSize()
void DesktopNotificationController::Toast::UpdateScaledImage(const SIZE& size)
{
BITMAP bm;
if(!GetObject(scaledImage, sizeof(bm), &bm) ||
if(!GetObject(scaled_image_, sizeof(bm), &bm) ||
bm.bmWidth != size.cx ||
bm.bmHeight != size.cy)
{
if(scaledImage) DeleteBitmap(scaledImage);
scaledImage = StretchBitmap(data->image, size.cx, size.cy);
if(scaled_image_) DeleteBitmap(scaled_image_);
scaled_image_ = StretchBitmap(data_->image, size.cx, size.cy);
}
}
@ -585,24 +585,24 @@ void DesktopNotificationController::Toast::UpdateContents()
{
Draw();
if(IsWindowVisible(hWnd))
if(IsWindowVisible(hwnd_))
{
RECT rc;
GetWindowRect(hWnd, &rc);
GetWindowRect(hwnd_, &rc);
POINT origin = { 0, 0 };
SIZE size = { rc.right - rc.left, rc.bottom - rc.top };
UpdateLayeredWindow(hWnd, NULL, nullptr, &size, hdc, &origin, 0, nullptr, 0);
UpdateLayeredWindow(hwnd_, NULL, nullptr, &size, hdc_, &origin, 0, nullptr, 0);
}
}
void DesktopNotificationController::Toast::Dismiss()
{
if(!isNonInteractive)
if(!is_non_interactive_)
{
// 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 the toast under
// the cursor and not collapse it while dismissing.
isNonInteractive = true;
is_non_interactive_ = true;
AutoDismiss();
}
@ -610,28 +610,28 @@ void DesktopNotificationController::Toast::Dismiss()
void DesktopNotificationController::Toast::AutoDismiss()
{
KillTimer(hWnd, TimerID_AutoDismiss);
KillTimer(hwnd_, TimerID_AutoDismiss);
StartEaseOut();
}
void DesktopNotificationController::Toast::CancelDismiss()
{
KillTimer(hWnd, TimerID_AutoDismiss);
easeOutActive = false;
easeOutPos = 0;
KillTimer(hwnd_, TimerID_AutoDismiss);
ease_out_active_ = false;
ease_out_pos_ = 0;
}
void DesktopNotificationController::Toast::ScheduleDismissal()
{
SetTimer(hWnd, TimerID_AutoDismiss, 4000, nullptr);
SetTimer(hwnd_, TimerID_AutoDismiss, 4000, nullptr);
}
void DesktopNotificationController::Toast::ResetContents()
{
if(scaledImage)
if(scaled_image_)
{
DeleteBitmap(scaledImage);
scaledImage = NULL;
DeleteBitmap(scaled_image_);
scaled_image_ = NULL;
}
Invalidate();
@ -639,23 +639,23 @@ void DesktopNotificationController::Toast::ResetContents()
void DesktopNotificationController::Toast::PopUp(int y)
{
verticalPosTarget = verticalPos = y;
vertical_pos_target_ = vertical_pos_ = y;
StartEaseIn();
}
void DesktopNotificationController::Toast::SetVerticalPosition(int y)
{
// Don't restart animation if current target is the same
if(y == verticalPosTarget)
if(y == vertical_pos_target_)
return;
// Make sure the new animation's origin is at the current position
verticalPos += (int)((verticalPosTarget - verticalPos) * stackCollapsePos);
vertical_pos_ += (int)((vertical_pos_target_ - vertical_pos_) * stack_collapse_pos_);
// Set new target position and start the animation
verticalPosTarget = y;
stackCollapseStart = GetTickCount();
data->controller->StartAnimation();
vertical_pos_target_ = y;
stack_collapse_start_ = GetTickCount();
data_->controller->StartAnimation();
}
HDWP DesktopNotificationController::Toast::Animate(HDWP hdwp, const POINT& origin)
@ -672,7 +672,7 @@ HDWP DesktopNotificationController::Toast::Animate(HDWP hdwp, const POINT& origi
ulw.hdcDst = NULL;
ulw.pptDst = nullptr;
ulw.psize = nullptr;
ulw.hdcSrc = hdc;
ulw.hdcSrc = hdc_;
ulw.pptSrc = &srcOrigin;
ulw.crKey = 0;
ulw.pblend = nullptr;
@ -688,27 +688,27 @@ HDWP DesktopNotificationController::Toast::Animate(HDWP hdwp, const POINT& origi
auto easeOutPos = AnimateEaseOut();
auto stackCollapsePos = AnimateStackCollapse();
auto yOffset = (verticalPosTarget - verticalPos) * stackCollapsePos;
auto yOffset = (vertical_pos_target_ - vertical_pos_) * stackCollapsePos;
size.cx = (int)(toastSize.cx * easeInPos);
size.cy = toastSize.cy;
size.cx = (int)(toast_size_.cx * easeInPos);
size.cy = toast_size_.cy;
pt.x = origin.x - size.cx;
pt.y = (int)(origin.y - verticalPos - yOffset - size.cy);
pt.y = (int)(origin.y - vertical_pos_ - yOffset - size.cy);
ulw.pptDst = &pt;
ulw.psize = &size;
if(easeInActive && easeInPos == 1.0f)
if(ease_in_active_ && easeInPos == 1.0f)
{
easeInActive = false;
ease_in_active_ = false;
ScheduleDismissal();
}
this->easeInPos = easeInPos;
this->stackCollapsePos = stackCollapsePos;
this->ease_in_pos_ = easeInPos;
this->stack_collapse_pos_ = stackCollapsePos;
if(easeOutPos != this->easeOutPos)
if(easeOutPos != this->ease_out_pos_)
{
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
@ -718,11 +718,11 @@ HDWP DesktopNotificationController::Toast::Animate(HDWP hdwp, const POINT& origi
ulw.pblend = &blend;
ulw.dwFlags = ULW_ALPHA;
this->easeOutPos = easeOutPos;
this->ease_out_pos_ = easeOutPos;
if(easeOutPos == 1.0f)
{
easeOutActive = false;
ease_out_active_ = false;
dwpFlags &= ~SWP_SHOWWINDOW;
dwpFlags |= SWP_HIDEWINDOW;
@ -731,46 +731,46 @@ HDWP DesktopNotificationController::Toast::Animate(HDWP hdwp, const POINT& origi
if(stackCollapsePos == 1.0f)
{
verticalPos = verticalPosTarget;
vertical_pos_ = vertical_pos_target_;
}
// `UpdateLayeredWindowIndirect` updates position, size, and transparency.
// `DeferWindowPos` updates z-order, and also position and size in case ULWI fails,
// which can happen when one of the dimensions is zero (e.g. at the beginning of ease-in).
auto ulwResult = UpdateLayeredWindowIndirect(hWnd, &ulw);
hdwp = DeferWindowPos(hdwp, hWnd, HWND_TOPMOST, pt.x, pt.y, size.cx, size.cy, dwpFlags);
auto ulwResult = UpdateLayeredWindowIndirect(hwnd_, &ulw);
hdwp = DeferWindowPos(hdwp, hwnd_, HWND_TOPMOST, pt.x, pt.y, size.cx, size.cy, dwpFlags);
return hdwp;
}
void DesktopNotificationController::Toast::StartEaseIn()
{
_ASSERT(!easeInActive);
easeInStart = GetTickCount();
easeInActive = true;
data->controller->StartAnimation();
_ASSERT(!ease_in_active_);
ease_in_start_ = GetTickCount();
ease_in_active_ = true;
data_->controller->StartAnimation();
}
void DesktopNotificationController::Toast::StartEaseOut()
{
_ASSERT(!easeOutActive);
easeOutStart = GetTickCount();
easeOutActive = true;
data->controller->StartAnimation();
_ASSERT(!ease_out_active_);
ease_out_start_ = GetTickCount();
ease_out_active_ = true;
data_->controller->StartAnimation();
}
bool DesktopNotificationController::Toast::IsStackCollapseActive() const
{
return (verticalPos != verticalPosTarget);
return (vertical_pos_ != vertical_pos_target_);
}
float DesktopNotificationController::Toast::AnimateEaseIn()
{
if(!easeInActive)
return easeInPos;
if(!ease_in_active_)
return ease_in_pos_;
constexpr float duration = 500.0f;
float time = std::min(duration, (float)(GetTickCount() - easeInStart)) / duration;
float time = std::min(duration, (float)(GetTickCount() - ease_in_start_)) / duration;
// decelerating exponential ease
const float a = -8.0f;
@ -781,11 +781,11 @@ float DesktopNotificationController::Toast::AnimateEaseIn()
float DesktopNotificationController::Toast::AnimateEaseOut()
{
if(!easeOutActive)
return easeOutPos;
if(!ease_out_active_)
return ease_out_pos_;
constexpr float duration = 120.0f;
float time = std::min(duration, (float)(GetTickCount() - easeOutStart)) / duration;
float time = std::min(duration, (float)(GetTickCount() - ease_out_start_)) / duration;
// accelerating circle ease
auto pos = 1.0f - std::sqrt(1 - time * time);
@ -796,10 +796,10 @@ float DesktopNotificationController::Toast::AnimateEaseOut()
float DesktopNotificationController::Toast::AnimateStackCollapse()
{
if(!IsStackCollapseActive())
return stackCollapsePos;
return stack_collapse_pos_;
constexpr float duration = 500.0f;
float time = std::min(duration, (float)(GetTickCount() - stackCollapseStart)) / duration;
float time = std::min(duration, (float)(GetTickCount() - stack_collapse_start_)) / duration;
// decelerating exponential ease
const float a = -8.0f;

View file

@ -17,7 +17,7 @@ public:
const std::shared_ptr<NotificationData>& GetNotification() const
{
return data;
return data_;
}
void ResetContents();
@ -28,21 +28,21 @@ public:
void SetVerticalPosition(int y);
int GetVerticalPosition() const
{
return verticalPosTarget;
return vertical_pos_target_;
}
int GetHeight() const
{
return toastSize.cy;
return toast_size_.cy;
}
HDWP Animate(HDWP hdwp, const POINT& origin);
bool IsAnimationActive() const
{
return easeInActive || easeOutActive || IsStackCollapseActive();
return ease_in_active_ || ease_out_active_ || IsStackCollapseActive();
}
bool IsHighlighted() const
{
_ASSERT(!(isHighlighted && !IsWindowVisible(hWnd)));
return isHighlighted;
_ASSERT(!(is_highlighted_ && !IsWindowVisible(hwnd_)));
return is_highlighted_;
}
private:
@ -73,27 +73,27 @@ private:
float AnimateStackCollapse();
private:
static constexpr const TCHAR className[] = TEXT("DesktopNotificationToast");
static constexpr const TCHAR class_name_[] = TEXT("DesktopNotificationToast");
const HWND hWnd;
HDC hdc;
HBITMAP bitmap = NULL;
const HWND hwnd_;
HDC hdc_;
HBITMAP bitmap_ = NULL;
const std::shared_ptr<NotificationData> data; // never null
const std::shared_ptr<NotificationData> data_; // never null
SIZE toastSize = {};
SIZE margin = {};
RECT closeButtonRect = {};
HBITMAP scaledImage = NULL;
SIZE toast_size_ = {};
SIZE margin_ = {};
RECT close_button_rect_ = {};
HBITMAP scaled_image_ = NULL;
int verticalPos = 0;
int verticalPosTarget = 0;
bool isNonInteractive = false;
bool easeInActive = false;
bool easeOutActive = false;
bool isContentUpdated = false, isHighlighted = false, isCloseHot = false;
DWORD easeInStart, easeOutStart, stackCollapseStart;
float easeInPos = 0, easeOutPos = 0, stackCollapsePos = 0;
int vertical_pos_ = 0;
int vertical_pos_target_ = 0;
bool is_non_interactive_ = false;
bool ease_in_active_ = false;
bool ease_out_active_ = false;
bool is_content_updated_ = false, is_highlighted_ = false, is_close_hot_ = false;
DWORD ease_in_start_, ease_out_start_, stack_collapse_start_;
float ease_in_pos_ = 0, ease_out_pos_ = 0, stack_collapse_pos_ = 0;
};
}

View file

@ -38,23 +38,23 @@ void Win32Notification::Show(const base::string16& title, const base::string16&
if(existing)
{
existing->tag.clear();
this->notificationRef = std::move(existing->notificationRef);
this->notificationRef.Set(title, msg, image);
existing->tag_.clear();
this->notification_ref_ = std::move(existing->notification_ref_);
this->notification_ref_.Set(title, msg, image);
}
else
{
this->notificationRef = presenter->AddNotification(title, msg, image);
this->notification_ref_ = presenter->AddNotification(title, msg, image);
}
this->tag = tag;
this->tag_ = tag;
if(image) DeleteObject(image);
}
void Win32Notification::Dismiss()
{
notificationRef.Close();
notification_ref_.Close();
}
}

View file

@ -13,18 +13,18 @@ public:
const DesktopNotificationController::Notification& GetRef() const
{
return notificationRef;
return notification_ref_;
}
const std::string& GetTag() const
{
return tag;
return tag_;
}
private:
DISALLOW_COPY_AND_ASSIGN(Win32Notification);
DesktopNotificationController::Notification notificationRef;
std::string tag;
DesktopNotificationController::Notification notification_ref_;
std::string tag_;
};
}