aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPComboBoxCell.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPComboBoxCell.m')
-rw-r--r--Source/SPComboBoxCell.m137
1 files changed, 137 insertions, 0 deletions
diff --git a/Source/SPComboBoxCell.m b/Source/SPComboBoxCell.m
new file mode 100644
index 00000000..15ddc1db
--- /dev/null
+++ b/Source/SPComboBoxCell.m
@@ -0,0 +1,137 @@
+//
+// SPComboBoxCell.m
+// sequel-pro
+//
+// Created by Max Lohrmann on 08.11.15.
+// Copyright (c) 2015 Max Lohrmann. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// More info at <https://github.com/sequelpro/sequelpro>
+
+#import "SPComboBoxCell.h"
+#import <objc/runtime.h>
+
+static NSString *_CellSelectionDidChangeNotification = @"NSComboBoxCellSelectionDidChangeNotification";
+static NSString *_CellWillPopUpNotification = @"NSComboBoxCellWillPopUpNotification";
+static NSString *_CellWillDismissNotification = @"NSComboBoxCellWillDismissNotification";
+
+@interface NSComboBoxCell (Apple_Private)
+- (IBAction)popUp:(id)sender;
+@end
+
+@interface SPComboBoxCell ()
+
+- (void)sp_selectionDidChange:(NSNotification *)notification;
+- (void)sp_cellWillPopUp:(NSNotification *)notification;
+- (void)sp_cellWillDismiss:(NSNotification *)notification;
+@end
+
+@implementation SPComboBoxCell
+
+@synthesize spDelegate;
+
+- (id)copyWithZone:(NSZone *)zone
+{
+ SPComboBoxCell *cpy = [super copyWithZone:zone];
+
+ cpy->spDelegate = [self spDelegate];
+
+ return cpy;
+}
+
+- (void)dealloc
+{
+ [self setSpDelegate:nil];
+ [super dealloc];
+}
+
+- (NSWindow *)spPopUpWindow
+{
+ NSWindow *popUp;
+ Ivar popUpVar = object_getInstanceVariable(self,"_popUp",(void **)&popUp);
+ if(popUpVar) {
+ const char *typeEnc = ivar_getTypeEncoding(popUpVar);
+ if(typeEnc[0] == '@' && [popUp isKindOfClass:[NSWindow class]]) { // it is an object and of class NSWindow
+ return popUp;
+ }
+ }
+ return nil;
+}
+
+- (void)popUp:(id)sender
+{
+ // this notification will be sent after the popup window is resized and moved to the correct position
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(sp_cellWillPopUp:)
+ name:_CellWillPopUpNotification
+ object:self];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(sp_cellWillDismiss:)
+ name:_CellWillDismissNotification
+ object:self];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(sp_selectionDidChange:)
+ name:_CellSelectionDidChangeNotification
+ object:self];
+
+ [super popUp:sender]; // this method won't return until the window is closed again
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:_CellSelectionDidChangeNotification
+ object:self];
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:_CellWillPopUpNotification
+ object:self];
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:_CellWillDismissNotification
+ object:self];
+}
+
+- (void)sp_selectionDidChange:(NSNotification *)notification
+{
+ if([[self spDelegate] respondsToSelector:@selector(comboBoxCellSelectionDidChange:)]) {
+ [[self spDelegate] comboBoxCellSelectionDidChange:self];
+ }
+}
+
+- (void)sp_cellWillPopUp:(NSNotification *)notification
+{
+ NSWindow *popUp = [self spPopUpWindow];
+ if(popUp && [[self spDelegate] respondsToSelector:@selector(comboBoxCell:willPopUpWindow:)]) {
+ [[self spDelegate] comboBoxCell:self willPopUpWindow:popUp];
+ }
+}
+
+- (void)sp_cellWillDismiss:(NSNotification *)notification
+{
+ NSWindow *popUp = [self spPopUpWindow];
+ if(popUp && [[self spDelegate] respondsToSelector:@selector(comboBoxCell:willDismissWindow:)]) {
+ [[self spDelegate] comboBoxCell:self willDismissWindow:popUp];
+ }
+}
+
+@end