macOS: Add VLCTintedImageButtonCell
authorMarvin Scholz <epirat07@gmail.com>
Sat, 24 Jun 2017 12:13:36 +0000 (14:13 +0200)
committerMarvin Scholz <epirat07@gmail.com>
Sat, 24 Jun 2017 12:13:36 +0000 (14:13 +0200)
This is a class for macOS versions lower than 10.10, where some image
buttons on dark backgrounds (or other colored backgrounds) would draw in
a dark color (usually black, for template images).
With this class, a tint color can be set for these buttons, it defaults
to white. This class is only intended to be used with template images.

extras/package/macosx/VLC.xcodeproj/project.pbxproj
modules/gui/macosx/Makefile.am
modules/gui/macosx/VLCTintedImageButtonCell.h [new file with mode: 0644]
modules/gui/macosx/VLCTintedImageButtonCell.m [new file with mode: 0644]

index 0518a80..bd71b16 100644 (file)
@@ -87,6 +87,7 @@
                6BF093F91EE0182B0049D8B0 /* VLCTimeField.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF093F81EE0182B0049D8B0 /* VLCTimeField.m */; };
                6BF5C5011EFE03CF008A9C12 /* VLCHUDStepperCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5001EFE03CF008A9C12 /* VLCHUDStepperCell.m */; };
                6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */; };
+               6BF5C5071EFE7E58008A9C12 /* VLCTintedImageButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5061EFE7E58008A9C12 /* VLCTintedImageButtonCell.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
                6BF5C5001EFE03CF008A9C12 /* VLCHUDStepperCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCHUDStepperCell.m; sourceTree = "<group>"; };
                6BF5C5021EFE66EF008A9C12 /* VLCHUDTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCHUDTableView.h; sourceTree = "<group>"; };
                6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCHUDTableView.m; sourceTree = "<group>"; };
+               6BF5C5051EFE7E58008A9C12 /* VLCTintedImageButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCTintedImageButtonCell.h; sourceTree = "<group>"; };
+               6BF5C5061EFE7E58008A9C12 /* VLCTintedImageButtonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCTintedImageButtonCell.m; sourceTree = "<group>"; };
                7D5678EB1D5BA1DC002698F3 /* VLCApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCApplication.h; sourceTree = "<group>"; };
                7D5678EC1D5BA1DC002698F3 /* VLCApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCApplication.m; sourceTree = "<group>"; };
                7D5678EE1D5BA397002698F3 /* VLCMainWindowControlsBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCMainWindowControlsBar.h; sourceTree = "<group>"; };
                        children = (
                                6B3BE42A1E6217CB008D098A /* VLCImageButton.h */,
                                6B3BE42B1E6217CB008D098A /* VLCImageButton.m */,
+                               6BF5C5051EFE7E58008A9C12 /* VLCTintedImageButtonCell.h */,
+                               6BF5C5061EFE7E58008A9C12 /* VLCTintedImageButtonCell.m */,
                                1C67C8A61D58C0A40079E1C1 /* VLCAboutWindowController.h */,
                                1C67C8A71D58C0A40079E1C1 /* VLCAboutWindowController.m */,
                                1C67C8A31D58C0980079E1C1 /* VLCHelpWindowController.h */,
                                1C3113A31E508C6900D4DD76 /* VLCCoreDialogProvider.m in Sources */,
                                1C3113A51E508C6900D4DD76 /* VLCCoreInteraction.m in Sources */,
                                1C3113A71E508C6900D4DD76 /* VLCDebugMessageWindowController.m in Sources */,
+                               6BF5C5071EFE7E58008A9C12 /* VLCTintedImageButtonCell.m in Sources */,
                                1C3113A91E508C6900D4DD76 /* VLCDocumentController.m in Sources */,
                                1C3113AB1E508C6900D4DD76 /* VLCExtensionsDialogProvider.m in Sources */,
                                1C3113AD1E508C6900D4DD76 /* VLCExtensionsManager.m in Sources */,
index 9e7a2ab..35dd88b 100644 (file)
@@ -96,6 +96,7 @@ libmacosx_plugin_la_SOURCES = \
        gui/macosx/VLCDefaultValueSlider.h gui/macosx/VLCDefaultValueSlider.m \
        gui/macosx/VLCDefaultValueSliderCell.h gui/macosx/VLCDefaultValueSliderCell.m \
        gui/macosx/VLCImageButton.h gui/macosx/VLCImageButton.m \
+       gui/macosx/VLCTintedImageButtonCell.h gui/macosx/VLCTintedImageButtonCell.m \
        gui/macosx/VLCTimeField.h gui/macosx/VLCTimeField.m
 
 # User interface compilation
diff --git a/modules/gui/macosx/VLCTintedImageButtonCell.h b/modules/gui/macosx/VLCTintedImageButtonCell.h
new file mode 100644 (file)
index 0000000..78791f9
--- /dev/null
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * VLCTintedImageButtonCell.h
+ *****************************************************************************
+ * Copyright (C) 2017 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+@interface VLCTintedImageButtonCell : NSButtonCell
+
+@property (nonatomic) IBInspectable NSColor *imageTintColor;
+
+@end
diff --git a/modules/gui/macosx/VLCTintedImageButtonCell.m b/modules/gui/macosx/VLCTintedImageButtonCell.m
new file mode 100644 (file)
index 0000000..afe64cb
--- /dev/null
@@ -0,0 +1,87 @@
+/*****************************************************************************
+ * VLCTintedImageButtonCell.m
+ *****************************************************************************
+ * Copyright (C) 2017 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCTintedImageButtonCell.h"
+#import "CompatibilityFixes.h"
+
+@interface VLCTintedImageButtonCell () {
+    NSMutableDictionary *_imageCache;
+}
+@end
+
+
+@implementation VLCTintedImageButtonCell
+
++ (void)load
+{
+    /* On 10.10+ we do not want custom drawing, therefore we swap out the implementation
+     * of the selectors below with their original implementations.
+     * Just calling super is not enough here, as the button would still draw in a different
+     * way, non vibrant with weird highlighting behaviour.
+     */
+    if (OSX_YOSEMITE_AND_HIGHER) {
+        swapoutOverride([VLCTintedImageButtonCell class], @selector(initWithCoder:));
+        swapoutOverride([VLCTintedImageButtonCell class], @selector(drawImage:withFrame:inView:));
+    }
+}
+
+- (instancetype)initWithCoder:(NSCoder *)coder
+{
+    self = [super initWithCoder:coder];
+    if (self) {
+        _imageCache = [NSMutableDictionary dictionary];
+        _imageTintColor = [NSColor whiteColor];
+    }
+    return self;
+}
+
+- (NSImage *)image:(NSImage*)image tintedWithColor:(NSColor *)tint
+{
+    image = [image copy];
+    if (tint) {
+        [image lockFocus];
+        [tint set];
+        NSRect imageRect = {NSZeroPoint, [image size]};
+        NSRectFillUsingOperation(imageRect, NSCompositeSourceAtop);
+        [image unlockFocus];
+        [image setTemplate:NO];
+    }
+    return image;
+}
+
+- (NSImage*)tintedImage:(NSImage*)image
+{
+    NSNumber *key = @((NSInteger)image);
+    if (![_imageCache objectForKey:key]) {
+        NSImage *tintedImg = [self image:image tintedWithColor:_imageTintColor];
+        [_imageCache setObject:tintedImg forKey:key];
+    }
+    return [_imageCache objectForKey:key];
+}
+
+- (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView
+{
+    [super drawImage:image withFrame:frame inView:controlView];
+}
+
+@end