Merge pull request #92826 from bruvzg/nat_icon_checks

Improve native menu and status indicator icons conversion and checks.
This commit is contained in:
Rémi Verschelde 2024-06-07 23:30:39 +02:00
commit a139cd611a
No known key found for this signature in database
GPG Key ID: C3336907360768E1
4 changed files with 44 additions and 88 deletions

View File

@ -3166,42 +3166,13 @@ void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) {
DisplayServer::IndicatorID DisplayServerMacOS::create_status_indicator(const Ref<Texture2D> &p_icon, const String &p_tooltip, const Callable &p_callback) { DisplayServer::IndicatorID DisplayServerMacOS::create_status_indicator(const Ref<Texture2D> &p_icon, const String &p_tooltip, const Callable &p_callback) {
NSImage *nsimg = nullptr; NSImage *nsimg = nullptr;
if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0) { if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
Ref<Image> img = p_icon->get_image(); Ref<Image> img = p_icon->get_image();
img = img->duplicate(); img = img->duplicate();
img->convert(Image::FORMAT_RGBA8); if (img->is_compressed()) {
img->decompress();
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:nullptr
pixelsWide:img->get_width()
pixelsHigh:img->get_height()
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:img->get_width() * 4
bitsPerPixel:32];
if (imgrep) {
uint8_t *pixels = [imgrep bitmapData];
int len = img->get_width() * img->get_height();
const uint8_t *r = img->get_data().ptr();
/* Premultiply the alpha channel */
for (int i = 0; i < len; i++) {
uint8_t alpha = r[i * 4 + 3];
pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255);
pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255);
pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255);
pixels[i * 4 + 3] = alpha;
}
nsimg = [[NSImage alloc] initWithSize:NSMakeSize(img->get_width(), img->get_height())];
if (nsimg) {
[nsimg addRepresentation:imgrep];
}
} }
nsimg = _convert_to_nsimg(img);
} }
IndicatorData idat; IndicatorData idat;
@ -3229,42 +3200,13 @@ void DisplayServerMacOS::status_indicator_set_icon(IndicatorID p_id, const Ref<T
ERR_FAIL_COND(!indicators.has(p_id)); ERR_FAIL_COND(!indicators.has(p_id));
NSImage *nsimg = nullptr; NSImage *nsimg = nullptr;
if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0) { if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
Ref<Image> img = p_icon->get_image(); Ref<Image> img = p_icon->get_image();
img = img->duplicate(); img = img->duplicate();
img->convert(Image::FORMAT_RGBA8); if (img->is_compressed()) {
img->decompress();
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:nullptr
pixelsWide:img->get_width()
pixelsHigh:img->get_height()
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:img->get_width() * 4
bitsPerPixel:32];
if (imgrep) {
uint8_t *pixels = [imgrep bitmapData];
int len = img->get_width() * img->get_height();
const uint8_t *r = img->get_data().ptr();
/* Premultiply the alpha channel */
for (int i = 0; i < len; i++) {
uint8_t alpha = r[i * 4 + 3];
pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255);
pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255);
pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255);
pixels[i * 4 + 3] = alpha;
}
nsimg = [[NSImage alloc] initWithSize:NSMakeSize(img->get_width(), img->get_height())];
if (nsimg) {
[nsimg addRepresentation:imgrep];
}
} }
nsimg = _convert_to_nsimg(img);
} }
NSStatusItem *item = indicators[p_id].item; NSStatusItem *item = indicators[p_id].item;

View File

@ -461,7 +461,7 @@ int NativeMenuMacOS::add_icon_item(const RID &p_rid, const Ref<Texture2D> &p_ico
obj->max_states = 0; obj->max_states = 0;
obj->state = 0; obj->state = 0;
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds && p_icon.is_valid()) { if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
obj->img = p_icon->get_image(); obj->img = p_icon->get_image();
obj->img = obj->img->duplicate(); obj->img = obj->img->duplicate();
if (obj->img->is_compressed()) { if (obj->img->is_compressed()) {
@ -492,7 +492,7 @@ int NativeMenuMacOS::add_icon_check_item(const RID &p_rid, const Ref<Texture2D>
obj->max_states = 0; obj->max_states = 0;
obj->state = 0; obj->state = 0;
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds && p_icon.is_valid()) { if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
obj->img = p_icon->get_image(); obj->img = p_icon->get_image();
obj->img = obj->img->duplicate(); obj->img = obj->img->duplicate();
if (obj->img->is_compressed()) { if (obj->img->is_compressed()) {
@ -543,7 +543,7 @@ int NativeMenuMacOS::add_icon_radio_check_item(const RID &p_rid, const Ref<Textu
obj->max_states = 0; obj->max_states = 0;
obj->state = 0; obj->state = 0;
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds && p_icon.is_valid()) { if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
obj->img = p_icon->get_image(); obj->img = p_icon->get_image();
obj->img = obj->img->duplicate(); obj->img = obj->img->duplicate();
if (obj->img->is_compressed()) { if (obj->img->is_compressed()) {
@ -1237,7 +1237,7 @@ void NativeMenuMacOS::set_item_icon(const RID &p_rid, int p_idx, const Ref<Textu
GodotMenuItem *obj = [menu_item representedObject]; GodotMenuItem *obj = [menu_item representedObject];
ERR_FAIL_NULL(obj); ERR_FAIL_NULL(obj);
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds && p_icon.is_valid()) { if (ds && p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
obj->img = p_icon->get_image(); obj->img = p_icon->get_image();
obj->img = obj->img->duplicate(); obj->img = obj->img->duplicate();
if (obj->img->is_compressed()) { if (obj->img->is_compressed()) {

View File

@ -3166,9 +3166,12 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
DisplayServer::IndicatorID DisplayServerWindows::create_status_indicator(const Ref<Texture2D> &p_icon, const String &p_tooltip, const Callable &p_callback) { DisplayServer::IndicatorID DisplayServerWindows::create_status_indicator(const Ref<Texture2D> &p_icon, const String &p_tooltip, const Callable &p_callback) {
HICON hicon = nullptr; HICON hicon = nullptr;
if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0) { if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
Ref<Image> img = p_icon->get_image(); Ref<Image> img = p_icon->get_image();
img = img->duplicate(); img = img->duplicate();
if (img->is_compressed()) {
img->decompress();
}
img->convert(Image::FORMAT_RGBA8); img->convert(Image::FORMAT_RGBA8);
int w = img->get_width(); int w = img->get_width();
@ -3236,9 +3239,12 @@ void DisplayServerWindows::status_indicator_set_icon(IndicatorID p_id, const Ref
ERR_FAIL_COND(!indicators.has(p_id)); ERR_FAIL_COND(!indicators.has(p_id));
HICON hicon = nullptr; HICON hicon = nullptr;
if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0) { if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
Ref<Image> img = p_icon->get_image(); Ref<Image> img = p_icon->get_image();
img = img->duplicate(); img = img->duplicate();
if (img->is_compressed()) {
img->decompress();
}
img->convert(Image::FORMAT_RGBA8); img->convert(Image::FORMAT_RGBA8);
int w = img->get_width(); int w = img->get_width();

View File

@ -35,6 +35,8 @@
#include "scene/resources/image_texture.h" #include "scene/resources/image_texture.h"
HBITMAP NativeMenuWindows::_make_bitmap(const Ref<Image> &p_img) const { HBITMAP NativeMenuWindows::_make_bitmap(const Ref<Image> &p_img) const {
p_img->convert(Image::FORMAT_RGBA8);
Vector2i texture_size = p_img->get_size(); Vector2i texture_size = p_img->get_size();
UINT image_size = texture_size.width * texture_size.height; UINT image_size = texture_size.width * texture_size.height;
@ -354,12 +356,14 @@ int NativeMenuWindows::add_icon_item(const RID &p_rid, const Ref<Texture2D> &p_i
item_data->checkable_type = CHECKABLE_TYPE_NONE; item_data->checkable_type = CHECKABLE_TYPE_NONE;
item_data->max_states = 0; item_data->max_states = 0;
item_data->state = 0; item_data->state = 0;
item_data->img = p_icon->get_image(); if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
item_data->img = item_data->img->duplicate(); item_data->img = p_icon->get_image();
if (item_data->img->is_compressed()) { item_data->img = item_data->img->duplicate();
item_data->img->decompress(); if (item_data->img->is_compressed()) {
item_data->img->decompress();
}
item_data->bmp = _make_bitmap(item_data->img);
} }
item_data->bmp = _make_bitmap(item_data->img);
Char16String label = p_label.utf16(); Char16String label = p_label.utf16();
MENUITEMINFOW item; MENUITEMINFOW item;
@ -394,12 +398,14 @@ int NativeMenuWindows::add_icon_check_item(const RID &p_rid, const Ref<Texture2D
item_data->checkable_type = CHECKABLE_TYPE_CHECK_BOX; item_data->checkable_type = CHECKABLE_TYPE_CHECK_BOX;
item_data->max_states = 0; item_data->max_states = 0;
item_data->state = 0; item_data->state = 0;
item_data->img = p_icon->get_image(); if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
item_data->img = item_data->img->duplicate(); item_data->img = p_icon->get_image();
if (item_data->img->is_compressed()) { item_data->img = item_data->img->duplicate();
item_data->img->decompress(); if (item_data->img->is_compressed()) {
item_data->img->decompress();
}
item_data->bmp = _make_bitmap(item_data->img);
} }
item_data->bmp = _make_bitmap(item_data->img);
Char16String label = p_label.utf16(); Char16String label = p_label.utf16();
MENUITEMINFOW item; MENUITEMINFOW item;
@ -467,12 +473,14 @@ int NativeMenuWindows::add_icon_radio_check_item(const RID &p_rid, const Ref<Tex
item_data->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; item_data->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON;
item_data->max_states = 0; item_data->max_states = 0;
item_data->state = 0; item_data->state = 0;
item_data->img = p_icon->get_image(); if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
item_data->img = item_data->img->duplicate(); item_data->img = p_icon->get_image();
if (item_data->img->is_compressed()) { item_data->img = item_data->img->duplicate();
item_data->img->decompress(); if (item_data->img->is_compressed()) {
item_data->img->decompress();
}
item_data->bmp = _make_bitmap(item_data->img);
} }
item_data->bmp = _make_bitmap(item_data->img);
Char16String label = p_label.utf16(); Char16String label = p_label.utf16();
MENUITEMINFOW item; MENUITEMINFOW item;
@ -1087,7 +1095,7 @@ void NativeMenuWindows::set_item_icon(const RID &p_rid, int p_idx, const Ref<Tex
if (item_data->bmp) { if (item_data->bmp) {
DeleteObject(item_data->bmp); DeleteObject(item_data->bmp);
} }
if (p_icon.is_valid()) { if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0 && p_icon->get_image().is_valid()) {
item_data->img = p_icon->get_image(); item_data->img = p_icon->get_image();
item_data->img = item_data->img->duplicate(); item_data->img = item_data->img->duplicate();
if (item_data->img->is_compressed()) { if (item_data->img->is_compressed()) {