From dff1594926eb9202e9f6f0f7df2d5f32f0c9b116 Mon Sep 17 00:00:00 2001 From: relikd Date: Tue, 6 Aug 2019 20:05:16 +0200 Subject: [PATCH] Blue dot for unread articles --- CHANGELOG.md | 1 + baRSS/Constants.h | 26 +++++++++++++++++ baRSS/Core Data/Feed+Ext.m | 1 - baRSS/Core Data/FeedArticle+Ext.m | 2 ++ baRSS/Helper/DrawImage.h | 7 ----- baRSS/Helper/DrawImage.m | 29 ++++++++++++++++++- baRSS/Info.plist | 2 +- .../Appearance Tab/SettingsAppearanceView.m | 2 +- baRSS/Status Bar Menu/BarStatusItem.m | 1 - 9 files changed, 59 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab9e9cd..5755fe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project does adhere to [Semantic Versioning](https://semver.org/spec/v2 ### Changed - *UI:* Interface builder files replaced with code equivalent +- *UI:* Mark unread articles with blue dot, instead of tick mark - *Settings, Feeds:* Single add button for feeds, groups, and separators - *Settings, Feeds:* Always append new items at the end - *Adding feed:* Display error reason if user cancels the creation of a new feed item diff --git a/baRSS/Constants.h b/baRSS/Constants.h index af9a07e..4db8e63 100644 --- a/baRSS/Constants.h +++ b/baRSS/Constants.h @@ -31,6 +31,29 @@ /// UTI type used for opml files static const NSPasteboardType UTI_OPML = @"org.opml"; + +#pragma mark - NSImageName constants + + +/// Default RSS icon (with border, with gradient, orange) +static NSImageName const RSSImageDefaultRSSIcon = @"RSSImageDefaultRSSIcon"; +/// Settings, global icon (menu bar, black) +static NSImageName const RSSImageSettingsGlobal = @"RSSImageSettingsGlobal"; +/// Settings, group icon (folder, black) +static NSImageName const RSSImageSettingsGroup = @"RSSImageSettingsGroup"; +/// Settings, feed icon (RSS, no border, no gradient, black) +static NSImageName const RSSImageSettingsFeed = @"RSSImageSettingsFeed"; +/// Menu bar, bar icon (RSS, with border, no gradient, orange) +static NSImageName const RSSImageMenuBarIconActive = @"RSSImageMenuBarIconActive"; +/// Menu bar, bar icon (RSS, with border, no gradient, paused, orange) +static NSImageName const RSSImageMenuBarIconPaused = @"RSSImageMenuBarIconPaused"; +/// Menu item, unread state icon (blue dot) +static NSImageName const RSSImageMenuItemUnread = @"RSSImageMenuItemUnread"; + + +#pragma mark - NSNotificationName constants + + /** @c notification.object is @c NSNumber of type @c NSUInteger. Represents number of feeds that are proccessed in background update. Sends @c 0 when all downloads are finished. @@ -64,6 +87,9 @@ static const NSNotificationName kNotificationTotalUnreadCountChanged = @"baRSS-n static const NSNotificationName kNotificationTotalUnreadCountReset = @"baRSS-notification-total-unread-count-reset"; +#pragma mark - Internal + + /** Internal developer method for benchmarking purposes. */ diff --git a/baRSS/Core Data/Feed+Ext.m b/baRSS/Core Data/Feed+Ext.m index be6ba67..7a5179e 100644 --- a/baRSS/Core Data/Feed+Ext.m +++ b/baRSS/Core Data/Feed+Ext.m @@ -23,7 +23,6 @@ #import "Feed+Ext.h" #import "Constants.h" #import "UserPrefs.h" -#import "DrawImage.h" #import "FeedMeta+Ext.h" #import "FeedGroup+Ext.h" #import "FeedArticle+Ext.h" diff --git a/baRSS/Core Data/FeedArticle+Ext.m b/baRSS/Core Data/FeedArticle+Ext.m index b1ff939..acaf4ed 100644 --- a/baRSS/Core Data/FeedArticle+Ext.m +++ b/baRSS/Core Data/FeedArticle+Ext.m @@ -67,6 +67,8 @@ item.title = [self shortArticleName]; item.enabled = (self.link.length > 0); item.state = (self.unread && [UserPrefs defaultYES:@"feedTickMark"] ? NSControlStateValueOn : NSControlStateValueOff); + item.onStateImage = [NSImage imageNamed:RSSImageMenuItemUnread]; + item.accessibilityLabel = (self.unread ? NSLocalizedString(@"article: unread", @"accessibility label, feed menu item") : NSLocalizedString(@"article: read", @"accessibility label, feed menu item")); item.toolTip = (self.abstract ? self.abstract : self.body); // fall back to body (html) item.representedObject = self.objectID; item.target = [self class]; diff --git a/baRSS/Helper/DrawImage.h b/baRSS/Helper/DrawImage.h index 83351e1..4d06572 100644 --- a/baRSS/Helper/DrawImage.h +++ b/baRSS/Helper/DrawImage.h @@ -36,11 +36,4 @@ IB_DESIGNABLE @end -static NSImageName const RSSImageSettingsGlobal = @"RSSImageSettingsGlobal"; -static NSImageName const RSSImageSettingsGroup = @"RSSImageSettingsGroup"; -static NSImageName const RSSImageSettingsFeed = @"RSSImageSettingsFeed"; -static NSImageName const RSSImageDefaultRSSIcon = @"RSSImageDefaultRSSIcon"; -static NSImageName const RSSImageMenuBarIconActive = @"RSSImageMenuBarIconActive"; -static NSImageName const RSSImageMenuBarIconPaused = @"RSSImageMenuBarIconPaused"; - void RegisterImageViewNames(void); diff --git a/baRSS/Helper/DrawImage.m b/baRSS/Helper/DrawImage.m index b22b9c9..ce174ac 100644 --- a/baRSS/Helper/DrawImage.m +++ b/baRSS/Helper/DrawImage.m @@ -21,6 +21,7 @@ // SOFTWARE. #import "DrawImage.h" +#import "Constants.h" @implementation NSColor (RandomColor) /// @return Color with random R, G, B values for testing purposes @@ -72,6 +73,12 @@ NS_INLINE void PathAddCircle(CGMutablePathRef path, CGFloat radius) { CGPathAddArc(path, NULL, radius, radius, radius, 0, M_PI * 2, YES); } +/// Add ring with @c radius and @c innerRadius +NS_INLINE void PathAddRing(CGMutablePathRef path, CGFloat radius, CGFloat innerRadius) { + CGPathAddArc(path, NULL, radius, radius, radius, 0, M_PI * 2, YES); + CGPathAddArc(path, NULL, radius, radius, innerRadius, 0, M_PI * -2, YES); +} + /// Add a single RSS icon radio wave NS_INLINE void PathAddRSSArc(CGMutablePathRef path, CGFloat radius, CGFloat thickness) { CGPathMoveToPoint(path, NULL, 0, radius + thickness); @@ -285,6 +292,25 @@ NS_INLINE void DrawRSSGradientIcon(CGRect r) { CGContextEOFillPath(c); } +/// Draw unread icon (blue dot for unread menu item) +NS_INLINE void DrawUnreadIcon(CGRect r, NSColor *color) { + CGFloat size = ShorterSide(r.size) / 2.0; + CGContextRef c = NSGraphicsContext.currentContext.CGContext; + CGMutablePathRef path = CGPathCreateMutable(); + SetContentScale(c, r.size, 0.8); + + CGContextSetFillColorWithColor(c, color.CGColor); + PathAddRing(path, size, size * 0.7); + CGContextAddPath(c, path); + CGContextEOFillPath(c); + + CGContextSetFillColorWithColor(c, [color colorWithAlphaComponent:0.5].CGColor); + PathAddCircle(path, size); + CGContextAddPath(c, path); + CGContextFillPath(c); + CGPathRelease(path); +} + #pragma mark - NSImage Name Registration @@ -299,10 +325,11 @@ NS_INLINE void Register(CGFloat size, NSImageName name, NSString *description, B /// Register all icons that require custom drawing in @c ImageNamed cache void RegisterImageViewNames(void) { const CGColorRef black = [NSColor controlTextColor].CGColor; + Register(16, RSSImageDefaultRSSIcon, NSLocalizedString(@"RSS icon", nil), ^(NSRect r) { DrawRSSGradientIcon(r); return YES; }); Register(16, RSSImageSettingsGlobal, NSLocalizedString(@"Global settings", nil), ^(NSRect r) { DrawGlobalIcon(r, black, NO); return YES; }); Register(16, RSSImageSettingsGroup, NSLocalizedString(@"Group settings", nil), ^(NSRect r) { DrawGroupIcon(r, black, NO); return YES; }); Register(16, RSSImageSettingsFeed, NSLocalizedString(@"Feed settings", nil), ^(NSRect r) { DrawRSSIcon(r, black, NO, YES); return YES; }); - Register(16, RSSImageDefaultRSSIcon, NSLocalizedString(@"RSS icon", nil), ^(NSRect r) { DrawRSSGradientIcon(r); return YES; }); Register(16, RSSImageMenuBarIconActive, NSLocalizedString(@"RSS menu bar icon", nil), ^(NSRect r) { DrawRSSIcon(r, [NSColor rssOrange].CGColor, YES, YES); return YES; }); Register(16, RSSImageMenuBarIconPaused, NSLocalizedString(@"RSS menu bar icon, paused", nil), ^(NSRect r) { DrawRSSIcon(r, [NSColor rssOrange].CGColor, YES, NO); return YES; }); + Register(12, RSSImageMenuItemUnread, NSLocalizedString(@"Unread icon", nil), ^(NSRect r) { DrawUnreadIcon(r, [NSColor systemBlueColor]); return YES; }); } diff --git a/baRSS/Info.plist b/baRSS/Info.plist index e313240..726f23a 100644 --- a/baRSS/Info.plist +++ b/baRSS/Info.plist @@ -60,7 +60,7 @@ CFBundleVersion - 9750 + 9859 LSApplicationCategoryType public.app-category.news LSMinimumSystemVersion diff --git a/baRSS/Preferences/Appearance Tab/SettingsAppearanceView.m b/baRSS/Preferences/Appearance Tab/SettingsAppearanceView.m index c0acd5e..87ce8b0 100644 --- a/baRSS/Preferences/Appearance Tab/SettingsAppearanceView.m +++ b/baRSS/Preferences/Appearance Tab/SettingsAppearanceView.m @@ -22,7 +22,7 @@ #import "SettingsAppearanceView.h" #import "NSView+Ext.h" -#import "DrawImage.h" +#import "Constants.h" #import "UserPrefs.h" @interface SettingsAppearanceView() diff --git a/baRSS/Status Bar Menu/BarStatusItem.m b/baRSS/Status Bar Menu/BarStatusItem.m index 3636111..565f18f 100644 --- a/baRSS/Status Bar Menu/BarStatusItem.m +++ b/baRSS/Status Bar Menu/BarStatusItem.m @@ -22,7 +22,6 @@ #import "BarStatusItem.h" #import "Constants.h" -#import "DrawImage.h" #import "FeedDownload.h" #import "StoreCoordinator.h" #import "UserPrefs.h"