NSDockTile - Implement methods to update the icon and show badge (#185)

NSDockTile - Implement methods to update the icon and show badge using a NSCustomImageRep. Link the NSDockTile view with the AppIcon window contentView.
GSTheme - add badgeColor color and corresponding methods to theme background, decoration and text color
This commit is contained in:
Gregory Casamento 2023-07-27 03:17:18 -04:00 committed by GitHub
parent a34867faee
commit f2b79365f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 196 additions and 15 deletions

View file

@ -2,7 +2,7 @@
<abstract>Useful/configurable drawing functions</abstract>
Copyright (C) 2004-2006 Free Software Foundation, Inc.
Copyright (C) 2004-2023 Free Software Foundation, Inc.
Author: Adam Fedor <fedor@gnu.org>
Author: Richard Frith-Macdonald <rfm@gnu.org>
@ -17,7 +17,7 @@
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUstep
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
@ -1328,6 +1328,12 @@ APPKIT_EXPORT_CLASS
boxType: (NSBoxType)boxType
borderType: (NSBorderType)borderType
inView: (NSBox *)box;
/* NSDockTile */
- (NSColor *) badgeBackgroundColor;
- (NSColor *) badgeDecorationColor;
- (NSColor *) badgeTextColor;
@end
/**

View file

@ -62,6 +62,7 @@ extern "C" {
@class NSMenuItem;
@class NSPasteboard;
@class NSWindow;
@class NSDockTile;
@class GSInfoPanel;
@ -221,6 +222,7 @@ APPKIT_EXPORT_CLASS
BOOL _windows_need_update;
NSImage *_app_icon;
NSWindow *_app_icon_window;
NSDockTile *_dock_tile;
NSMutableArray *_hidden;
NSMutableArray *_inactive;
NSWindow *_hidden_key;

View file

@ -36,6 +36,7 @@ extern "C" {
#endif
@class NSView, NSString;
@class NSImageRep;
APPKIT_EXPORT_CLASS
@interface NSDockTile : NSObject
@ -45,6 +46,9 @@ APPKIT_EXPORT_CLASS
id _owner;
BOOL _showsApplicationBadge;
NSString *_badgeLabel;
NSImage *_appIconImage;
NSImageRep *_imageRep;
NSImage *_dockTileImage;
}
- (NSView *) contentView;

View file

@ -2,7 +2,7 @@
<abstract>The theme methods for drawing controls</abstract>
Copyright (C) 2004-2010 Free Software Foundation, Inc.
Copyright (C) 2004-2023 Free Software Foundation, Inc.
Author: Adam Fedor <fedor@gnu.org>
Date: Jan 2004
@ -676,6 +676,45 @@
return color;
}
- (NSColor *) badgeBackgroundColor
{
NSColor *color;
color = [self colorNamed: @"badgeColor"
state: GSThemeNormalState];
if (color == nil)
{
color = [NSColor redColor];
}
return color;
}
- (NSColor *) badgeDecorationColor
{
NSColor *color;
color = [self colorNamed: @"badgeColor"
state: GSThemeSelectedState];
if (color == nil)
{
color = [NSColor lightGrayColor];
}
return color;
}
- (NSColor *) badgeTextColor
{
NSColor *color;
color = [self colorNamed: @"badgeColor"
state: GSThemeHighlightedState];
if (color == nil)
{
color = [NSColor whiteColor];
}
return color;
}
- (void) drawToolbarRect: (NSRect)aRect
frame: (NSRect)viewFrame
borderMask: (unsigned int)borderMask

View file

@ -71,6 +71,7 @@
#import "AppKit/NSImage.h"
#import "AppKit/NSMenu.h"
#import "AppKit/NSMenuItem.h"
#import "AppKit/NSDockTile.h"
#import "AppKit/NSNibLoading.h"
#import "AppKit/NSPageLayout.h"
#import "AppKit/NSPanel.h"
@ -1244,6 +1245,7 @@ static BOOL _isAutolaunchChecked = NO;
TEST_RELEASE(_app_icon);
TEST_RELEASE(_app_icon_window);
TEST_RELEASE(_dock_tile);
TEST_RELEASE(_infoPanel);
/* Destroy the default context */
@ -2458,6 +2460,15 @@ image.</p><p>See Also: -applicationIconImage</p>
return _app_icon_window;
}
- (NSDockTile *) dockTile
{
if (!_dock_tile)
{
_dock_tile = [[NSDockTile alloc] init];
[_dock_tile setContentView: [_app_icon_window contentView]];
}
return _dock_tile;
}
/*
* Hiding and arranging windows
*/

View file

@ -1,29 +1,43 @@
/* Implementation of class NSDockTile
Copyright (C) 2019 Free Software Foundation, Inc.
Copyright (C) 2019-2023 Free Software Foundation, Inc.
By: Gregory John Casamento <greg.casamento@gmail.com>
Riccardo Mottola <rm@gnu.org>
Date: Sat Nov 16 21:11:06 EST 2019
This file is part of the GNUstep Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110 USA.
*/
#import <AppKit/NSDockTile.h>
#import <AppKit/NSView.h>
#import "AppKit/NSApplication.h"
#import "AppKit/NSDockTile.h"
#import "AppKit/NSView.h"
#import "AppKit/NSImage.h"
#import "AppKit/NSImageRep.h"
#import "AppKit/NSCustomImageRep.h"
#import "AppKit/NSFont.h"
#import "AppKit/NSStringDrawing.h"
#import "AppKit/NSAttributedString.h"
#import "AppKit/NSBezierPath.h"
#import "GNUstepGUI/GSTheme.h"
#import "GNUstepGUI/GSDisplayServer.h"
@implementation NSDockTile
@ -32,11 +46,24 @@
self = [super init];
if (self != nil)
{
NSRect rect = NSMakeRect(0,0,48,48);
_size = rect.size;
GSDisplayServer *server = GSCurrentServer();
NSSize size = [server iconSize];
NSRect rect = NSMakeRect(0, 0, size.width, size.height);
_size = size;
_contentView = [[NSView alloc] initWithFrame: rect];
_badgeLabel = nil;
_owner = nil;
_showsApplicationBadge = YES;
_appIconImage = [NSImage imageNamed: @"NSApplicationIcon"];
RETAIN(_appIconImage);
_imageRep = [[NSCustomImageRep alloc] initWithDrawSelector: @selector(draw) delegate: self];
[_imageRep setSize: [_appIconImage size]];
_dockTileImage = [[NSImage alloc] initWithSize: [_appIconImage size]];
[_dockTileImage setCacheMode: NSImageCacheNever]; // Only needed because NSImage caches NSCustomImageReps
[_dockTileImage addRepresentation: _imageRep];
RELEASE(_imageRep);
[NSApp setApplicationIconImage: _dockTileImage];
}
return self;
}
@ -45,6 +72,8 @@
{
RELEASE(_contentView);
RELEASE(_badgeLabel);
RELEASE(_appIconImage);
RELEASE(_dockTileImage);
[super release];
}
@ -57,8 +86,8 @@
{
ASSIGN(_contentView, contentView);
}
- (NSSize) size
- (NSSize) size
{
return _size;
}
@ -81,6 +110,7 @@
- (void) setShowsApplicationBadge: (BOOL)flag
{
_showsApplicationBadge = flag;
[self display];
}
- (NSString *) badgeLabel
@ -91,6 +121,7 @@
- (void) setBadgeLabel: (NSString *)label
{
ASSIGNCOPY(_badgeLabel, label);
[self display];
}
- (void) display
@ -98,5 +129,93 @@
[_contentView setNeedsDisplay: YES];
}
@end
- (void)draw
{
[_appIconImage compositeToPoint: NSZeroPoint operation: NSCompositeCopy];
if (_showsApplicationBadge && _badgeLabel)
{
NSMutableDictionary *attrs;
NSPoint textLocation;
NSRect discRect;
NSSize discSize;
NSSize textSize;
int pad;
NSBezierPath *p;
NSPoint point;
CGFloat radius;
NSSize imageSize;
NSColor *badgeBackColor;
NSColor *badgeDecorationColor;
NSColor *badgeTextColor;
NSString *displayString;
badgeBackColor = [[GSTheme theme] badgeBackgroundColor];
badgeDecorationColor = [[GSTheme theme] badgeDecorationColor];
badgeTextColor = [[GSTheme theme] badgeTextColor];
imageSize = [_appIconImage size];
displayString = _badgeLabel;
if ([_badgeLabel length] > 5)
{
displayString = [NSString stringWithFormat: @"%@\u2026%@", [_badgeLabel substringToIndex: 2], [_badgeLabel substringFromIndex: [_badgeLabel length]-2]];
}
attrs = [[NSMutableDictionary alloc] init];
[attrs setObject: [NSFont boldSystemFontOfSize: imageSize.width/5] forKey: NSFontAttributeName];
[attrs setObject: badgeTextColor forKey: NSForegroundColorAttributeName];
textSize = [displayString sizeWithAttributes: attrs];
pad = imageSize.width / 10;
discSize = textSize;
if (discSize.width < 12)
{
discSize.width = 12;
}
discSize.height += pad;
discSize.width += pad;
discRect = NSMakeRect(imageSize.width - discSize.width,
imageSize.height - discSize.height,
discSize.width,
discSize.height);
textLocation = NSMakePoint(imageSize.width - discSize.width + (discSize.width - textSize.width)/2,
imageSize.height - discSize.height + (discSize.height - textSize.height)/2);
radius = discRect.size.height / 2.0;
point = discRect.origin;
point.x += radius;
point.y += radius - 0.5;
// left half-circle
p = [NSBezierPath bezierPath];
[p appendBezierPathWithArcWithCenter: point
radius: radius
startAngle: 90.0
endAngle: 270.0];
// line to first point and right halfcircle
point.x += discRect.size.width - discRect.size.height;
[p appendBezierPathWithArcWithCenter: point
radius: radius
startAngle: 270.0
endAngle: 90.0];
[p closePath];
[badgeBackColor set];
[p fill];
[p setLineWidth: 1.5];
[badgeDecorationColor set];
[p stroke];
[displayString drawAtPoint: textLocation withAttributes: attrs];
RELEASE(attrs);
}
}
@end