Cocoa: Update unified toolbar area on toolbar hide

Add setContentBorderAreaEnabled() which us used to
enable or disable an area. Used together with
registerContentBorderArea() this allows changing the
border area geometry and enabled status independently.

Add section to the QToolBar show/hide event handler
which calls setContentBorderAreaEnabled().

Make sure QToolBar and QToolBarLayout uses the same
identifier - the QToolBar object pointer.

Rename enableContentBorderArea -> setContentBorderEnabled.
The "ContentBorder" is now the entire unified toolbar
area while "ContentBorderArea"s are the sub-areas
covered by toolbars.

Change-Id: I339f381a50856e048ae40e7ffadd6a8a510c4994
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
bb10
Morten Johan Sørvig 2014-03-31 12:19:20 +02:00 committed by The Qt Project
parent b2a6c9ec3e
commit 0f2acaf1cb
7 changed files with 85 additions and 44 deletions

View File

@ -133,16 +133,19 @@ private:
// deregisters.
static void registerTouchWindow(QWindow *window, bool enable);
// Request a unified title and toolbar look for the window.
// Enable the unified title and toolbar area for a window.
static void setContentBorderEnabled(QWindow *window, bool enable);
// Set the size of the unified title and toolbar area.
static void setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness);
// Request a unified title and toolbar look for the window by registering
// an area. Multiple callers can register areas and the platform plugin
// Set the size for a unified toolbar content border area.
// Multiple callers can register areas and the platform plugin
// will extend the "unified" area to cover them.
static void registerContentBorderArea(QWindow *window, quintptr identifer, int upper, int lower);
// Enable the unified title and toolbar area.
static void enableContentBorderArea(QWindow *window, bool enable);
// Enables or disiables a content border area.
static void setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable);
// Sets a NSToolbar instance for the given QWindow. The
// toolbar will be attached to the native NSWindow when

View File

@ -127,8 +127,10 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderThickness);
if (resource.toLower() == "registercontentborderarea")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerContentBorderArea);
if (resource.toLower() == "enablecontentborderarea")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::enableContentBorderArea);
if (resource.toLower() == "setcontentborderareaenabled")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderAreaEnabled);
if (resource.toLower() == "setcontentborderenabled")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderEnabled);
if (resource.toLower() == "setnstoolbar")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar);
@ -301,14 +303,24 @@ void QCocoaNativeInterface::registerContentBorderArea(QWindow *window, quintptr
cocoaWindow->registerContentBorderArea(identifier, upper, lower);
}
void QCocoaNativeInterface::enableContentBorderArea(QWindow *window, bool enable)
void QCocoaNativeInterface::setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable)
{
if (!window)
return;
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
if (cocoaWindow)
cocoaWindow->enableContentBorderArea(enable);
cocoaWindow->setContentBorderAreaEnabled(identifier, enable);
}
void QCocoaNativeInterface::setContentBorderEnabled(QWindow *window, bool enable)
{
if (!window)
return;
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
if (cocoaWindow)
cocoaWindow->setContentBorderEnabled(enable);
}
void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)

View File

@ -211,7 +211,8 @@ public:
void registerTouch(bool enable);
void setContentBorderThickness(int topThickness, int bottomThickness);
void registerContentBorderArea(quintptr identifier, int upper, int lower);
void enableContentBorderArea(bool enable);
void setContentBorderAreaEnabled(quintptr identifier, bool enable);
void setContentBorderEnabled(bool enable);
void applyContentBorderThickness(NSWindow *window);
void updateNSToolbar();
@ -289,7 +290,8 @@ public: // for QNSView
NSApplicationPresentationOptions m_presentationOptions;
struct BorderRange {
BorderRange(int u, int l) : upper(u), lower(l) { }
BorderRange(quintptr i, int u, int l) : identifier(i), upper(u), lower(l) { }
quintptr identifier;
int upper;
int lower;
bool operator<(BorderRange const& right) const {
@ -297,6 +299,7 @@ public: // for QNSView
}
};
QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false)
};
QT_END_NAMESPACE

View File

@ -1596,28 +1596,17 @@ void QCocoaWindow::setContentBorderThickness(int topThickness, int bottomThickne
void QCocoaWindow::registerContentBorderArea(quintptr identifier, int upper, int lower)
{
m_contentBorderAreas.insert(identifier, BorderRange(upper, lower));
// Find consecutive registered border areas, starting from the top.
QList<BorderRange> ranges = m_contentBorderAreas.values();
std::sort(ranges.begin(), ranges.end());
m_topContentBorderThickness = 0;
foreach (BorderRange range, ranges) {
// Is this sub-range adjacent to or overlaping the
// existing total border area range? If so merge
// it into the total range,
if (range.upper <= (m_topContentBorderThickness + 1))
m_topContentBorderThickness = qMax(m_topContentBorderThickness, range.lower);
else
break;
}
m_bottomContentBorderThickness = 0; // (not supported)
if (m_drawContentBorderGradient)
applyContentBorderThickness(m_nsWindow);
m_contentBorderAreas.insert(identifier, BorderRange(identifier, upper, lower));
applyContentBorderThickness(m_nsWindow);
}
void QCocoaWindow::enableContentBorderArea(bool enable)
void QCocoaWindow::setContentBorderAreaEnabled(quintptr identifier, bool enable)
{
m_enabledContentBorderAreas.insert(identifier, enable);
applyContentBorderThickness(m_nsWindow);
}
void QCocoaWindow::setContentBorderEnabled(bool enable)
{
m_drawContentBorderGradient = enable;
applyContentBorderThickness(m_nsWindow);
@ -1633,17 +1622,33 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
return;
}
// Find consecutive registered border areas, starting from the top.
QList<BorderRange> ranges = m_contentBorderAreas.values();
std::sort(ranges.begin(), ranges.end());
int effectiveTopContentBorderThickness = m_topContentBorderThickness;
foreach (BorderRange range, ranges) {
// Skip disiabled ranges (typically hidden tool bars)
if (!m_enabledContentBorderAreas.value(range.identifier, false))
continue;
// Is this sub-range adjacent to or overlaping the
// existing total border area range? If so merge
// it into the total range,
if (range.upper <= (effectiveTopContentBorderThickness + 1))
effectiveTopContentBorderThickness = qMax(effectiveTopContentBorderThickness, range.lower);
else
break;
}
int effectiveBottomContentBorderThickness = m_bottomContentBorderThickness;
[window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
if (m_topContentBorderThickness > 0) {
[window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMaxYEdge];
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
}
[window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge];
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
if (m_bottomContentBorderThickness > 0) {
[window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMinYEdge];
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
}
[window setContentBorderThickness:effectiveBottomContentBorderThickness forEdge:NSMinYEdge];
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
}
void QCocoaWindow::updateNSToolbar()

View File

@ -1513,12 +1513,12 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
nativeInterface->nativeResourceFunctionForIntegration("enableContentBorderArea");
nativeInterface->nativeResourceFunctionForIntegration("setContentBorderEnabled");
if (!function)
return; // Not Cocoa platform plugin.
typedef void (*EnableContentBorderAreaFunction)(QWindow *window, bool enable);
(reinterpret_cast<EnableContentBorderAreaFunction>(function))(window()->windowHandle(), set);
typedef void (*SetContentBorderEnabledFunction)(QWindow *window, bool enable);
(reinterpret_cast<SetContentBorderEnabledFunction>(function))(window()->windowHandle(), set);
}
#endif

View File

@ -1040,6 +1040,21 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup)
return false;
}
#ifdef Q_OS_OSX
static void enableMacToolBar(QToolBar *toolbar, bool enable)
{
QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled");
if (!function)
return; // Not Cocoa platform plugin.
typedef void (*SetContentBorderAreaEnabledFunction)(QWindow *window, void *identifier, bool enabled);
(reinterpret_cast<SetContentBorderAreaEnabledFunction>(function))(toolbar->window()->windowHandle(), toolbar, enable);
}
#endif
/*! \reimp */
bool QToolBar::event(QEvent *event)
{
@ -1062,6 +1077,9 @@ bool QToolBar::event(QEvent *event)
// fallthrough intended
case QEvent::Show:
d->toggleViewAction->setChecked(event->type() == QEvent::Show);
#ifdef Q_OS_OSX
enableMacToolBar(this, event->type() == QEvent::Show);
#endif
emit visibilityChanged(event->type() == QEvent::Show);
break;
case QEvent::ParentChange:

View File

@ -369,9 +369,9 @@ void QToolBarLayout::updateMacBorderMetrics()
typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, void *identifier, int upper, int lower);
if (mainWindow->toolBarArea(tb) == Qt::TopToolBarArea) {
(reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, upper.y(), lower.y());
(reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), tb, upper.y(), lower.y());
} else {
(reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, 0, 0);
(reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), tb, 0, 0);
}
#endif
}