summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoahelpers.mm
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@qt.io>2016-10-24 14:07:33 -0700
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2016-11-16 05:19:44 +0000
commit27aeeac6eeb11150b505f8ffde6e87e157c22c90 (patch)
treec1515bc75eec952567eac8aeecbfedeab09d73b7 /src/plugins/platforms/cocoa/qcocoahelpers.mm
parent1a43199fcea1bcec1ebf1a1a12cd3dcb942d67b4 (diff)
Cocoa Dialog Helpers: Refactor OK-Cancel buttons view
Since virtually all the logic is shared between QNSColorPanelDelegate and QNSFontPanelDelegate, we extract the added buttons and layouting logic and move it into its own class. This requires the two afore mentioned Objective C classes to satisfy the QNSPanelDelegate protocol. Change-Id: Ie26e758f5db71920896d930a4f3644b51a1ce3fa Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoahelpers.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index c57567bdd6..01fbb7bad2 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -300,3 +300,117 @@ QString qt_mac_removeAmpersandEscapes(QString s)
}
QT_END_NAMESPACE
+
+/*! \internal
+
+ This NSView derived class is used to add OK/Cancel
+ buttons to NSColorPanel and NSFontPanel. It replaces
+ the panel's content view, while reparenting the former
+ content view into itself. It also takes care of setting
+ the target-action for the OK/Cancel buttons and making
+ sure the layout is consistent.
+ */
+@implementation QNSPanelContentsWrapper
+
+- (instancetype)initWithPanelDelegate:(id<QT_MANGLE_NAMESPACE(QNSPanelDelegate)>)panelDelegate
+{
+ if ((self = [super initWithFrame:NSZeroRect])) {
+ // create OK and Cancel buttons and add these as subviews
+ _okButton = [self createButtonWithTitle:"&OK"];
+ _okButton.action = @selector(onOkClicked);
+ _okButton.target = panelDelegate;
+
+ _cancelButton = [self createButtonWithTitle:"Cancel"];
+ _cancelButton.action = @selector(onCancelClicked);
+ _cancelButton.target = panelDelegate;
+
+ _panelContents = nil;
+
+ _panelContentsMargins = NSEdgeInsetsMake(0, 0, 0, 0);
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [_okButton release];
+ _okButton = nil;
+ [_cancelButton release];
+ _cancelButton = nil;
+
+ _panelContents = nil;
+
+ [super dealloc];
+}
+
+- (NSButton *)createButtonWithTitle:(const char *)title
+{
+ NSButton *button = [[NSButton alloc] initWithFrame:NSZeroRect];
+ button.buttonType = NSMomentaryLightButton;
+ button.bezelStyle = NSRoundedBezelStyle;
+ const QString &cleanTitle = QPlatformTheme::removeMnemonics(QCoreApplication::translate("QDialogButtonBox", title));
+ // FIXME: Not obvious, from Cocoa's documentation, that QString::toNSString() makes a deep copy
+ button.title = (NSString *)cleanTitle.toCFString();
+ ((NSButtonCell *)button.cell).font =
+ [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
+ [self addSubview:button];
+ return button;
+}
+
+- (void)layout
+{
+ static const CGFloat ButtonMinWidth = 78.0; // 84.0 for Carbon
+ static const CGFloat ButtonMinHeight = 32.0;
+ static const CGFloat ButtonSpacing = 0.0;
+ static const CGFloat ButtonTopMargin = 0.0;
+ static const CGFloat ButtonBottomMargin = 7.0;
+ static const CGFloat ButtonSideMargin = 9.0;
+
+ NSSize frameSize = self.frame.size;
+
+ [self.okButton sizeToFit];
+ NSSize okSizeHint = self.okButton.frame.size;
+
+ [self.cancelButton sizeToFit];
+ NSSize cancelSizeHint = self.cancelButton.frame.size;
+
+ const CGFloat buttonWidth = qMin(qMax(ButtonMinWidth,
+ qMax(okSizeHint.width, cancelSizeHint.width)),
+ CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5));
+ const CGFloat buttonHeight = qMax(ButtonMinHeight,
+ qMax(okSizeHint.height, cancelSizeHint.height));
+
+ NSRect okRect = { { frameSize.width - ButtonSideMargin - buttonWidth,
+ ButtonBottomMargin },
+ { buttonWidth, buttonHeight } };
+ self.okButton.frame = okRect;
+ self.okButton.needsDisplay = YES;
+
+ NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - buttonWidth,
+ ButtonBottomMargin },
+ { buttonWidth, buttonHeight } };
+ self.cancelButton.frame = cancelRect;
+ self.cancelButton.needsDisplay = YES;
+
+ // The third view should be the original panel contents. Cache it.
+ if (!self.panelContents)
+ for (NSView *view in self.subviews)
+ if (view != self.okButton && view != self.cancelButton) {
+ _panelContents = view;
+ break;
+ }
+
+ const CGFloat buttonBoxHeight = ButtonBottomMargin + buttonHeight + ButtonTopMargin;
+ const NSRect panelContentsFrame = NSMakeRect(
+ self.panelContentsMargins.left,
+ buttonBoxHeight + self.panelContentsMargins.bottom,
+ frameSize.width - (self.panelContentsMargins.left + self.panelContentsMargins.right),
+ frameSize.height - buttonBoxHeight - (self.panelContentsMargins.top + self.panelContentsMargins.bottom));
+ self.panelContents.frame = panelContentsFrame;
+ self.panelContents.needsDisplay = YES;
+
+ self.needsDisplay = YES;
+}
+
+@end