5#include <AppKit/AppKit.h>
7#include <QtCore/qdebug.h>
8#include <QtCore/qtimer.h>
9#include <qpa/qplatformtheme.h>
14#include "private/qcoregraphics_p.h"
18@interface QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) : NSObject<NSWindowDelegate, QNSPanelDelegate>
19- (
void)restoreOriginalContentView;
21- (
void)finishOffWithCode:(NSInteger)code;
24QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
26@implementation QNSColorPanelDelegate {
28 NSColorPanel *mColorPanel;
29 QCocoaColorDialogHelper *mHelper;
30 NSView *mStolenContentView;
31 QNSPanelContentsWrapper *mPanelButtons;
33 NSInteger mResultCode;
34 BOOL mDialogIsExecuting;
36 BOOL mClosingDueToKnownButton;
42 mColorPanel = [NSColorPanel sharedColorPanel];
44 mStolenContentView = nil;
46 mResultCode = NSModalResponseCancel;
47 mDialogIsExecuting =
false;
49 mClosingDueToKnownButton =
false;
51 [mColorPanel setRestorable:NO];
53 [[NSNotificationCenter defaultCenter] addObserver:self
54 selector:@selector(colorChanged:)
55 name:NSColorPanelColorDidChangeNotification
58 [[NSNotificationCenter defaultCenter] addObserver:self
59 selector:@selector(windowWillClose:)
60 name:NSWindowWillCloseNotification
69 [mStolenContentView release];
70 [mColorPanel setDelegate:nil];
71 [[NSNotificationCenter defaultCenter] removeObserver:self];
76- (
void)setDialogHelper:(QCocoaColorDialogHelper *)helper
80 if (mHelper->options()->testOption(QColorDialogOptions::NoButtons)) {
81 [self restoreOriginalContentView];
82 }
else if (!mStolenContentView) {
84 mStolenContentView = mColorPanel.contentView;
85 [mStolenContentView retain];
86 mColorPanel.contentView = nil;
89 mPanelButtons = [[QNSPanelContentsWrapper alloc] initWithPanelDelegate:self];
90 [mPanelButtons addSubview:mStolenContentView];
91 mColorPanel.contentView = mPanelButtons;
92 mColorPanel.defaultButtonCell = mPanelButtons.okButton.cell;
101- (
void)colorChanged:(NSNotification *)notification
103 Q_UNUSED(notification);
104 [self updateQtColor];
107- (
void)windowWillClose:(NSNotification *)notification
109 Q_UNUSED(notification);
110 if (mPanelButtons && mHelper && !mClosingDueToKnownButton) {
111 mClosingDueToKnownButton =
true;
112 emit mHelper->reject();
116- (
void)restoreOriginalContentView
118 if (mStolenContentView) {
120 [mStolenContentView removeFromSuperview];
121 [mColorPanel setContentView:mStolenContentView];
122 [mStolenContentView release];
123 mStolenContentView = nil;
124 [mPanelButtons release];
131 mClosingDueToKnownButton =
true;
133 [self updateQtColor];
134 [self finishOffWithCode:NSModalResponseOK];
137- (
void)onCancelClicked
140 mClosingDueToKnownButton =
true;
143 [self finishOffWithCode:NSModalResponseCancel];
154 NSColor *componentColor = [[mColorPanel color] colorUsingType:NSColorTypeComponentBased];
155 switch (componentColor.colorSpace.colorSpaceModel)
157 case NSColorSpaceModelGray: {
158 CGFloat white = 0, alpha = 0;
159 [componentColor getWhite:&white alpha:&alpha];
160 mQtColor.setRgbF(white, white, white, alpha);
162 case NSColorSpaceModelRGB: {
163 CGFloat red = 0, green = 0, blue = 0, alpha = 0;
164 [componentColor getRed:&red green:&green blue:&blue alpha:&alpha];
165 mQtColor.setRgbF(red, green, blue, alpha);
167 case NSColorSpaceModelCMYK: {
168 CGFloat cyan = 0, magenta = 0, yellow = 0, black = 0, alpha = 0;
169 [componentColor getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
170 mQtColor.setCmykF(cyan, magenta, yellow, black, alpha);
173 qWarning(
"QNSColorPanelDelegate: Unsupported color space model");
178 emit mHelper->currentColorChanged(mQtColor);
181- (
void)showModelessPanel
183 mDialogIsExecuting =
false;
185 mClosingDueToKnownButton =
false;
194 dispatch_async(dispatch_get_main_queue(), ^{
195 [mColorPanel makeKeyAndOrderFront:mColorPanel];
199- (BOOL)runApplicationModalPanel
201 mDialogIsExecuting =
true;
202 [mColorPanel setDelegate:self];
203 [mColorPanel setContinuous:YES];
207 qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
210 QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
212 [NSApp runModalForWindow:mColorPanel];
213 mDialogIsExecuting =
false;
217 QCoreApplication::eventDispatcher()->wakeUp();
219 return (mResultCode == NSModalResponseOK);
222- (QPlatformDialogHelper::DialogCode)dialogResultCode
224 return (mResultCode == NSModalResponseOK) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
227- (BOOL)windowShouldClose:(id)window
231 [self updateQtColor];
232 if (mDialogIsExecuting) {
233 [self finishOffWithCode:NSModalResponseCancel];
237 emit mHelper->reject();
242- (
void)finishOffWithCode:(NSInteger)code
245 if (mDialogIsExecuting) {
251 [NSApp stopModalWithCode:code];
259 if (mResultCode == NSModalResponseCancel) {
260 emit mHelper->reject();
262 emit mHelper->accept();
272class QCocoaColorPanel
277 mDelegate = [[QNSColorPanelDelegate alloc] init];
285 void init(QCocoaColorDialogHelper *helper)
287 [mDelegate setDialogHelper:helper];
290 void cleanup(QCocoaColorDialogHelper *helper)
292 if (mDelegate->mHelper == helper)
293 mDelegate->mHelper =
nullptr;
302 return [mDelegate runApplicationModalPanel];
305 bool show(Qt::WindowModality windowModality, QWindow *parent)
308 if (windowModality != Qt::ApplicationModal)
309 [mDelegate showModelessPanel];
316 [mDelegate closePanel];
319 QColor currentColor()
const
321 return mDelegate->mQtColor;
324 void setCurrentColor(
const QColor &color)
328 if (color.alpha() < 255)
329 [mDelegate->mColorPanel setShowsAlpha:YES];
332 const QColor::Spec spec = color.spec();
333 if (spec == QColor::Cmyk) {
334 nsColor = [NSColor colorWithDeviceCyan:color.cyanF()
335 magenta:color.magentaF()
336 yellow:color.yellowF()
338 alpha:color.alphaF()];
340 nsColor = [NSColor colorWithCalibratedRed:color.redF()
343 alpha:color.alphaF()];
345 mDelegate->mQtColor = color;
346 [mDelegate->mColorPanel setColor:nsColor];
350 QNSColorPanelDelegate *mDelegate;
355QCocoaColorDialogHelper::QCocoaColorDialogHelper()
359QCocoaColorDialogHelper::~QCocoaColorDialogHelper()
361 sharedColorPanel()->cleanup(
this);
364void QCocoaColorDialogHelper::exec()
366 if (sharedColorPanel()->exec())
372bool QCocoaColorDialogHelper::show(Qt::WindowFlags, Qt::WindowModality windowModality, QWindow *parent)
374 if (windowModality == Qt::ApplicationModal)
375 windowModality = Qt::WindowModal;
380 [[NSColorPanel sharedColorPanel] setShowsAlpha:
381 options()->testOption(QColorDialogOptions::ShowAlphaChannel)];
383 sharedColorPanel()->init(
this);
384 return sharedColorPanel()->show(windowModality, parent);
387void QCocoaColorDialogHelper::hide()
389 sharedColorPanel()->hide();
392void QCocoaColorDialogHelper::setCurrentColor(
const QColor &color)
394 sharedColorPanel()->init(
this);
395 sharedColorPanel()->setCurrentColor(color);
398QColor QCocoaColorDialogHelper::currentColor()
const
400 return sharedColorPanel()->currentColor();
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)