Implement Fl_Window::icon() and default_icon() for macOS

The implementation is effective for macOS 10.10 and above.
Demo program test/device uses the new implementation.
This commit is contained in:
ManoloFLTK 2020-01-11 14:51:30 +01:00
parent 006d71c663
commit 2990717d6e
6 changed files with 80 additions and 11 deletions

View File

@ -582,6 +582,7 @@ void Fl_Cocoa_Screen_Driver::breakMacEventLoop()
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14
if (views_use_CA) [(FLView*)[self contentView] reset_aux_bitmap];
#endif
[[self standardWindowButton:NSWindowDocumentIconButton] setImage:nil];
[super close];
// when a fullscreen window is closed, windowDidResize may be sent after the close message was sent
// and before the FLWindow receives the final dealloc message
@ -1133,6 +1134,7 @@ static FLTextView *fltextview_instance = nil;
- (BOOL)windowShouldClose:(id)fl;
- (void)anyWindowWillClose:(NSNotification *)notif;
- (void)doNothing:(id)unused;
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu;
@end
@ -1390,6 +1392,9 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
{
return;
}
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu {
return NO;
}
@end
@interface FLAppDelegate : NSObject
@ -3075,6 +3080,16 @@ Fl_X* Fl_Cocoa_Window_Driver::makeWindow()
[cw setLevel:winlevel];
q_set_window_title(cw, w->label(), w->iconlabel());
NSImage *icon = icon_image; // is a window or default icon present?
if (!icon) icon = ((Fl_Cocoa_Screen_Driver*)Fl::screen_driver())->default_icon;
if (icon && (winstyle & NSTitledWindowMask) && w->label() && strlen(w->label())>0) {
[cw setRepresentedFilename:[NSString stringWithFormat:@"/%@", [cw title]]];
NSButton *icon_button = [cw standardWindowButton:NSWindowDocumentIconButton];
if (icon_button) {
[icon setSize:[icon_button frame].size];
[icon_button setImage:icon];
}
}
if (!force_position()) {
if (w->modal()) {
[cw center];
@ -4435,6 +4450,52 @@ char *Fl_Darwin_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Pre
return filename;
}
Fl_Cocoa_Window_Driver::~Fl_Cocoa_Window_Driver()
{
if (shape_data_) {
if (shape_data_->mask) {
CGImageRelease(shape_data_->mask);
}
delete shape_data_;
}
[icon_image release];
}
static NSImage* rgb_to_nsimage(const Fl_RGB_Image *rgb) {
if (!rgb) return nil;
int ld = rgb->ld();
if (!ld) ld = rgb->w() * rgb->d();
NSImage *win_icon = nil;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (fl_mac_os_version >= 101000) {
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:rgb->w() pixelsHigh:rgb->h()
bitsPerSample:8 samplesPerPixel:rgb->d() hasAlpha:!(rgb->d() & 1) isPlanar:NO
colorSpaceName:(rgb->d()<=2) ? NSDeviceWhiteColorSpace : NSDeviceRGBColorSpace
bitmapFormat:NSAlphaNonpremultipliedBitmapFormat bytesPerRow:ld bitsPerPixel:rgb->d()*8]; // 10.4
memcpy([bitmap bitmapData], rgb->array, rgb->h() * ld);
win_icon = [[NSImage alloc] initWithSize:NSMakeSize(0, 0)];
[win_icon addRepresentation:bitmap];
[bitmap release];
}
#endif
return win_icon;
}
void Fl_Cocoa_Window_Driver::icons(const Fl_RGB_Image *icons[], int count) {
[icon_image release];
icon_image = nil;
if (count >= 1 && pWindow->border() && pWindow->label() && strlen(pWindow->label())) {
icon_image = rgb_to_nsimage(icons[0]);
}
}
void Fl_Cocoa_Screen_Driver::default_icons(const Fl_RGB_Image *icons[], int count) {
[default_icon release];
default_icon = nil;
if (count >= 1) {
default_icon = rgb_to_nsimage(icons[0]);
}
}
//
// End of "$Id$".

View File

@ -41,6 +41,11 @@
class Fl_Window;
class Fl_Input;
class Fl_RGB_Image;
#ifdef __OBJC__
@class NSImage;
#else
class NSImage;
#endif
class FL_EXPORT Fl_Cocoa_Screen_Driver : public Fl_Screen_Driver
{
@ -54,6 +59,7 @@ protected:
static int insertion_point_height;
static bool insertion_point_location_is_valid;
public:
NSImage *default_icon;
Fl_Cocoa_Screen_Driver();
static int next_marked_length; // next length of marked text after current marked text will have been replaced
static void breakMacEventLoop();
@ -100,6 +106,7 @@ public:
virtual float scale(int n) {return scale_;}
virtual void scale(int n, float f) { scale_ = f;}
virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins);
virtual void default_icons(const Fl_RGB_Image *icons[], int count);
private:
float scale_;
};

View File

@ -79,6 +79,7 @@ static Fl_Text_Editor::Key_Binding extra_bindings[] = {
Fl_Cocoa_Screen_Driver::Fl_Cocoa_Screen_Driver() {
text_editor_extra_key_bindings = extra_bindings;
scale_ = 1.;
default_icon = nil;
}

View File

@ -33,12 +33,14 @@ class Fl_Window;
#ifdef __OBJC__
@class CALayer;
@class NSCursor;
@class NSImage;
@class FLWindow;
@class NSOpenGLContext;
@class NSOpenGLPixelFormat;
#else
class CALayer;
class NSCursor;
class NSImage;
class FLWindow;
class NSOpenGLContext;
class NSOpenGLPixelFormat;
@ -153,6 +155,10 @@ public:
static void GLcontext_makecurrent(NSOpenGLContext*); // uses Objective-c
static void GL_cleardrawable(void); // uses Objective-c
static void gl_start(NSOpenGLContext*); // uses Objective-c
//icons
virtual void icons(const Fl_RGB_Image *icons[], int count);
NSImage *icon_image;
};
#endif // FL_COCOA_WINDOW_DRIVER_H

View File

@ -52,17 +52,7 @@ Fl_Cocoa_Window_Driver::Fl_Cocoa_Window_Driver(Fl_Window *win)
{
cursor = nil;
window_flags_ = 0;
}
Fl_Cocoa_Window_Driver::~Fl_Cocoa_Window_Driver()
{
if (shape_data_) {
if (shape_data_->mask) {
CGImageRelease(shape_data_->mask);
}
delete shape_data_;
}
icon_image = NULL;
}

View File

@ -754,6 +754,10 @@ int main(int argc, char ** argv) {
w3->end();
w2->end();
Fl_RGB_Image *rgba_icon = new Fl_RGB_Image(pixmap);
Fl_Window::default_icon(rgba_icon);
//w2->icon(rgba_icon);
delete rgba_icon;
w2->show(argc, argv);
Fl::run();