Make it possible to get different size of icons from ICO

This commit is contained in:
Cheng Zhao 2016-05-20 17:51:05 +09:00
parent 0059e7bcf9
commit ea2807c890
3 changed files with 38 additions and 35 deletions

View file

@ -24,13 +24,8 @@ namespace atom {
namespace api { namespace api {
Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image) Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
: image_(isolate, image.ToV8()), : tray_icon_(TrayIcon::Create()) {
tray_icon_(TrayIcon::Create()) { SetImage(isolate, image);
#if defined(OS_WIN)
tray_icon_->SetImage(image->GetHICON());
#else
tray_icon_->SetImage(image->image());
#endif
tray_icon_->AddObserver(this); tray_icon_->AddObserver(this);
} }
@ -104,7 +99,7 @@ void Tray::OnDragEnded() {
void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) { void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) {
image_.Reset(isolate, image.ToV8()); image_.Reset(isolate, image.ToV8());
#if defined(OS_WIN) #if defined(OS_WIN)
tray_icon_->SetImage(image->GetHICON()); tray_icon_->SetImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
#else #else
tray_icon_->SetImage(image->image()); tray_icon_->SetImage(image->image());
#endif #endif
@ -114,7 +109,7 @@ void Tray::SetPressedImage(v8::Isolate* isolate,
mate::Handle<NativeImage> image) { mate::Handle<NativeImage> image) {
pressed_image_.Reset(isolate, image.ToV8()); pressed_image_.Reset(isolate, image.ToV8());
#if defined(OS_WIN) #if defined(OS_WIN)
tray_icon_->SetPressedImage(image->GetHICON()); tray_icon_->SetPressedImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
#else #else
tray_icon_->SetPressedImage(image->image()); tray_icon_->SetPressedImage(image->image());
#endif #endif
@ -145,7 +140,8 @@ void Tray::DisplayBalloon(mate::Arguments* args,
#if defined(OS_WIN) #if defined(OS_WIN)
tray_icon_->DisplayBalloon( tray_icon_->DisplayBalloon(
icon.IsEmpty() ? NULL : icon->GetHICON(), title, content); icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
title, content);
#else #else
tray_icon_->DisplayBalloon( tray_icon_->DisplayBalloon(
icon.IsEmpty() ? gfx::Image() : icon->image(), title, content); icon.IsEmpty() ? gfx::Image() : icon->image(), title, content);

View file

@ -4,10 +4,6 @@
#include "atom/common/api/atom_api_native_image.h" #include "atom/common/api/atom_api_native_image.h"
#if defined(OS_WIN)
#include <commctrl.h>
#endif
#include <string> #include <string>
#include <vector> #include <vector>
@ -146,7 +142,7 @@ bool IsTemplateFilename(const base::FilePath& path) {
#endif #endif
#if defined(OS_WIN) #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 // If file is in asar archive, we extract it to a temp file so LoadImage can
// load it. // load it.
base::FilePath asar_path, relative_path; base::FilePath asar_path, relative_path;
@ -159,9 +155,9 @@ base::win::ScopedHICON ReadICOFromPath(const base::FilePath& path) {
} }
// Load the icon from file. // Load the icon from file.
HICON icon = NULL; return base::win::ScopedHICON(static_cast<HICON>(
LoadIconMetric(NULL, image_path.value().c_str(), LIM_SMALL, &icon); LoadImage(NULL, image_path.value().c_str(), IMAGE_ICON, size, size,
return base::win::ScopedHICON(icon); LR_LOADFROMFILE)));
} }
void ReadImageSkiaFromICO(gfx::ImageSkia* image, HICON icon) { void ReadImageSkiaFromICO(gfx::ImageSkia* image, HICON icon) {
@ -179,13 +175,12 @@ NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image)
} }
#if defined(OS_WIN) #if defined(OS_WIN)
NativeImage::NativeImage(v8::Isolate* isolate, base::win::ScopedHICON&& hicon) NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path)
: hicon_(std::move(hicon)) { : hicon_path_(hicon_path) {
if (hicon_.get()) { // Use the 256x256 icon as fallback icon.
gfx::ImageSkia image_skia; gfx::ImageSkia image_skia;
ReadImageSkiaFromICO(&image_skia, hicon_.get()); ReadImageSkiaFromICO(&image_skia, GetHICON(256));
image_ = gfx::Image(image_skia); image_ = gfx::Image(image_skia);
}
Init(isolate); Init(isolate);
} }
#endif #endif
@ -193,13 +188,23 @@ NativeImage::NativeImage(v8::Isolate* isolate, base::win::ScopedHICON&& hicon)
NativeImage::~NativeImage() {} NativeImage::~NativeImage() {}
#if defined(OS_WIN) #if defined(OS_WIN)
HICON NativeImage::GetHICON() { HICON NativeImage::GetHICON(int size) {
if (hicon_.get()) auto iter = hicons_.find(size);
return hicon_.get(); 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()) if (image_.IsEmpty())
return NULL; return NULL;
hicon_ = std::move(IconUtil::CreateHICONFromSkBitmap(image_.AsBitmap())); hicons_[size] = std::move(
return hicon_.get(); IconUtil::CreateHICONFromSkBitmap(image_.AsBitmap()));
return hicons_[size].get();
} }
#endif #endif
@ -292,9 +297,8 @@ mate::Handle<NativeImage> NativeImage::CreateFromPath(
base::FilePath image_path = NormalizePath(path); base::FilePath image_path = NormalizePath(path);
if (image_path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) { if (image_path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) {
#if defined(OS_WIN) #if defined(OS_WIN)
base::win::ScopedHICON hicon = ReadICOFromPath(image_path);
return mate::CreateHandle(isolate, return mate::CreateHandle(isolate,
new NativeImage(isolate, std::move(hicon))); new NativeImage(isolate, image_path));
#endif #endif
} else { } else {
gfx::ImageSkia image_skia; gfx::ImageSkia image_skia;

View file

@ -5,6 +5,7 @@
#ifndef ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_ #ifndef ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
#define ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_ #define ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
#include <map>
#include <string> #include <string>
#include "native_mate/handle.h" #include "native_mate/handle.h"
@ -12,6 +13,7 @@
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#if defined(OS_WIN) #if defined(OS_WIN)
#include "base/files/file_path.h"
#include "base/win/scoped_gdi_object.h" #include "base/win/scoped_gdi_object.h"
#endif #endif
@ -53,7 +55,7 @@ class NativeImage : public mate::Wrappable<NativeImage> {
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
#if defined(OS_WIN) #if defined(OS_WIN)
HICON GetHICON(); HICON GetHICON(int size);
#endif #endif
const gfx::Image& image() const { return image_; } const gfx::Image& image() const { return image_; }
@ -61,7 +63,7 @@ class NativeImage : public mate::Wrappable<NativeImage> {
protected: protected:
NativeImage(v8::Isolate* isolate, const gfx::Image& image); NativeImage(v8::Isolate* isolate, const gfx::Image& image);
#if defined(OS_WIN) #if defined(OS_WIN)
NativeImage(v8::Isolate* isolate, base::win::ScopedHICON&& hicon); NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path);
#endif #endif
~NativeImage() override; ~NativeImage() override;
@ -81,7 +83,8 @@ class NativeImage : public mate::Wrappable<NativeImage> {
bool IsTemplateImage(); bool IsTemplateImage();
#if defined(OS_WIN) #if defined(OS_WIN)
base::win::ScopedHICON hicon_; base::FilePath hicon_path_;
std::map<int, base::win::ScopedHICON> hicons_;
#endif #endif
gfx::Image image_; gfx::Image image_;