From ea2807c89054c83d527d128e838620c40a53e568 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 20 May 2016 17:51:05 +0900 Subject: [PATCH] Make it possible to get different size of icons from ICO --- atom/browser/api/atom_api_tray.cc | 16 +++----- atom/common/api/atom_api_native_image.cc | 48 +++++++++++++----------- atom/common/api/atom_api_native_image.h | 9 +++-- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index edfc1d13fef1..5de3b63a4ce7 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -24,13 +24,8 @@ namespace atom { namespace api { Tray::Tray(v8::Isolate* isolate, mate::Handle image) - : image_(isolate, image.ToV8()), - tray_icon_(TrayIcon::Create()) { -#if defined(OS_WIN) - tray_icon_->SetImage(image->GetHICON()); -#else - tray_icon_->SetImage(image->image()); -#endif + : tray_icon_(TrayIcon::Create()) { + SetImage(isolate, image); tray_icon_->AddObserver(this); } @@ -104,7 +99,7 @@ void Tray::OnDragEnded() { void Tray::SetImage(v8::Isolate* isolate, mate::Handle image) { image_.Reset(isolate, image.ToV8()); #if defined(OS_WIN) - tray_icon_->SetImage(image->GetHICON()); + tray_icon_->SetImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON))); #else tray_icon_->SetImage(image->image()); #endif @@ -114,7 +109,7 @@ void Tray::SetPressedImage(v8::Isolate* isolate, mate::Handle image) { pressed_image_.Reset(isolate, image.ToV8()); #if defined(OS_WIN) - tray_icon_->SetPressedImage(image->GetHICON()); + tray_icon_->SetPressedImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON))); #else tray_icon_->SetPressedImage(image->image()); #endif @@ -145,7 +140,8 @@ void Tray::DisplayBalloon(mate::Arguments* args, #if defined(OS_WIN) tray_icon_->DisplayBalloon( - icon.IsEmpty() ? NULL : icon->GetHICON(), title, content); + icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)), + title, content); #else tray_icon_->DisplayBalloon( icon.IsEmpty() ? gfx::Image() : icon->image(), title, content); diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 5f15bad831bd..970f22cc68a5 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -4,10 +4,6 @@ #include "atom/common/api/atom_api_native_image.h" -#if defined(OS_WIN) -#include -#endif - #include #include @@ -146,7 +142,7 @@ bool IsTemplateFilename(const base::FilePath& path) { #endif #if defined(OS_WIN) -base::win::ScopedHICON ReadICOFromPath(const base::FilePath& path) { +base::win::ScopedHICON ReadICOFromPath(int size, const base::FilePath& path) { // If file is in asar archive, we extract it to a temp file so LoadImage can // load it. base::FilePath asar_path, relative_path; @@ -159,9 +155,9 @@ base::win::ScopedHICON ReadICOFromPath(const base::FilePath& path) { } // Load the icon from file. - HICON icon = NULL; - LoadIconMetric(NULL, image_path.value().c_str(), LIM_SMALL, &icon); - return base::win::ScopedHICON(icon); + return base::win::ScopedHICON(static_cast( + LoadImage(NULL, image_path.value().c_str(), IMAGE_ICON, size, size, + LR_LOADFROMFILE))); } void ReadImageSkiaFromICO(gfx::ImageSkia* image, HICON icon) { @@ -179,13 +175,12 @@ NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image) } #if defined(OS_WIN) -NativeImage::NativeImage(v8::Isolate* isolate, base::win::ScopedHICON&& hicon) - : hicon_(std::move(hicon)) { - if (hicon_.get()) { - gfx::ImageSkia image_skia; - ReadImageSkiaFromICO(&image_skia, hicon_.get()); - image_ = gfx::Image(image_skia); - } +NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path) + : hicon_path_(hicon_path) { + // Use the 256x256 icon as fallback icon. + gfx::ImageSkia image_skia; + ReadImageSkiaFromICO(&image_skia, GetHICON(256)); + image_ = gfx::Image(image_skia); Init(isolate); } #endif @@ -193,13 +188,23 @@ NativeImage::NativeImage(v8::Isolate* isolate, base::win::ScopedHICON&& hicon) NativeImage::~NativeImage() {} #if defined(OS_WIN) -HICON NativeImage::GetHICON() { - if (hicon_.get()) - return hicon_.get(); +HICON NativeImage::GetHICON(int size) { + auto iter = hicons_.find(size); + if (iter != hicons_.end()) + return iter->second.get(); + + // First try loading the icon with specified size. + if (!hicon_path_.empty()) { + hicons_[size] = std::move(ReadICOFromPath(size, hicon_path_)); + return hicons_[size].get(); + } + + // Then convert the image to ICO. if (image_.IsEmpty()) return NULL; - hicon_ = std::move(IconUtil::CreateHICONFromSkBitmap(image_.AsBitmap())); - return hicon_.get(); + hicons_[size] = std::move( + IconUtil::CreateHICONFromSkBitmap(image_.AsBitmap())); + return hicons_[size].get(); } #endif @@ -292,9 +297,8 @@ mate::Handle NativeImage::CreateFromPath( base::FilePath image_path = NormalizePath(path); if (image_path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) { #if defined(OS_WIN) - base::win::ScopedHICON hicon = ReadICOFromPath(image_path); return mate::CreateHandle(isolate, - new NativeImage(isolate, std::move(hicon))); + new NativeImage(isolate, image_path)); #endif } else { gfx::ImageSkia image_skia; diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index f79654d39e72..de4db4c0f382 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -5,6 +5,7 @@ #ifndef ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_ #define ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_ +#include #include #include "native_mate/handle.h" @@ -12,6 +13,7 @@ #include "ui/gfx/image/image.h" #if defined(OS_WIN) +#include "base/files/file_path.h" #include "base/win/scoped_gdi_object.h" #endif @@ -53,7 +55,7 @@ class NativeImage : public mate::Wrappable { v8::Local prototype); #if defined(OS_WIN) - HICON GetHICON(); + HICON GetHICON(int size); #endif const gfx::Image& image() const { return image_; } @@ -61,7 +63,7 @@ class NativeImage : public mate::Wrappable { protected: NativeImage(v8::Isolate* isolate, const gfx::Image& image); #if defined(OS_WIN) - NativeImage(v8::Isolate* isolate, base::win::ScopedHICON&& hicon); + NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path); #endif ~NativeImage() override; @@ -81,7 +83,8 @@ class NativeImage : public mate::Wrappable { bool IsTemplateImage(); #if defined(OS_WIN) - base::win::ScopedHICON hicon_; + base::FilePath hicon_path_; + std::map hicons_; #endif gfx::Image image_;