diff --git a/krita/ui/canvas/kis_abstract_canvas_widget.h b/krita/ui/canvas/kis_abstract_canvas_widget.h --- a/krita/ui/canvas/kis_abstract_canvas_widget.h +++ b/krita/ui/canvas/kis_abstract_canvas_widget.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2007 Boudewijn Rempt , (C) + * Copyright (C) 2015 Michael Abrahams * * 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 @@ -28,8 +29,11 @@ class KisCanvas2; class KisCanvasDecoration; class KisDisplayFilter; +class KisDisplayColorConverter; +class QBitArray; #include "kis_types.h" +#include "kis_ui_types.h" class KisAbstractCanvasWidget @@ -45,22 +49,40 @@ virtual KoToolProxy * toolProxy() const = 0; - /** - * Draw the specified decorations on the view. - */ + /// Draw the specified decorations on the view. virtual void drawDecorations(QPainter & gc, const QRect &updateWidgetRect) const = 0; virtual void addDecoration(KisCanvasDecoration* deco) = 0; + virtual KisCanvasDecoration* decoration(const QString& id) const = 0; virtual void setDecorations(const QList &) = 0; + virtual QList decorations() const = 0; /// set the specified display filter on the canvas virtual void setDisplayFilter(KisDisplayFilter *displayFilter) = 0; virtual void setWrapAroundViewingMode(bool value) = 0; + // Called from KisCanvas2::channelSelectionChanged + virtual void channelSelectionChanged(QBitArray channelFlags) = 0; + + // Called from KisCanvas2::slotSetDisplayProfile + virtual void setDisplayProfile(KisDisplayColorConverter *colorConverter) = 0; + + // Called from KisCanvas2::disconnectCurrentCanvas + virtual void disconnectCurrentCanvas() = 0; + + // Called from KisCanvas2::finishResizingImage + virtual void finishResizingImage(qint32 w, qint32 h) = 0; + + // Called from KisCanvas2::startUpdateProjection + virtual KisUpdateInfoSP startUpdateCanvasProjection(const QRect & rc, QBitArray channelFlags) = 0; + + // Called from KisCanvas2::updateCanvasProjection + virtual QRect updateCanvasProjection(KisUpdateInfoSP info) = 0; + /** * Returns true if the asynchromous engine of the canvas * (e.g. openGL pipeline) is busy with processing of the previous diff --git a/krita/ui/canvas/kis_canvas2.cpp b/krita/ui/canvas/kis_canvas2.cpp --- a/krita/ui/canvas/kis_canvas2.cpp +++ b/krita/ui/canvas/kis_canvas2.cpp @@ -66,7 +66,6 @@ #ifdef HAVE_OPENGL #include "opengl/kis_opengl_canvas2.h" -#include "opengl/kis_opengl_image_textures.h" #endif #include "opengl/kis_opengl.h" @@ -112,9 +111,6 @@ int openGLFilterMode; #endif KisToolProxy *toolProxy; -#ifdef HAVE_OPENGL - KisOpenGLImageTexturesSP openGLImageTextures; -#endif KisPrescaledProjectionSP prescaledProjection; bool vastScrolling; @@ -258,19 +254,7 @@ m_d->channelFlags = image->rootLayer()->channelFlags(); image->barrierLock(); - - if (m_d->currentCanvasIsOpenGL) { -#ifdef HAVE_OPENGL - Q_ASSERT(m_d->openGLImageTextures); - m_d->openGLImageTextures->setChannelFlags(m_d->channelFlags); -#else - Q_ASSERT_X(0, "KisCanvas2::setChannelFlags", "Bad use of setChannelFlags(). It shouldn't have happened =("); -#endif - } else { - Q_ASSERT(m_d->prescaledProjection); - m_d->prescaledProjection->setChannelFlags(m_d->channelFlags); - } - + m_d->canvasWidget->channelSelectionChanged(m_d->channelFlags); startUpdateInPatches(image->bounds()); image->unlock(); @@ -383,24 +367,11 @@ void KisCanvas2::createOpenGLCanvas() { -#ifdef HAVE_OPENGL KisConfig cfg; m_d->openGLFilterMode = cfg.openGLFilteringMode(); m_d->currentCanvasIsOpenGL = true; - - m_d->openGLImageTextures = KisOpenGLImageTextures::getImageTextures(m_d->view->image(), - m_d->displayColorConverter->monitorProfile(), - m_d->displayColorConverter->renderingIntent(), - m_d->displayColorConverter->conversionFlags()); - - KisOpenGLCanvas2 *canvasWidget = new KisOpenGLCanvas2(this, m_d->coordinatesConverter, 0, m_d->openGLImageTextures); - canvasWidget->setDisplayFilter(m_d->displayColorConverter->displayFilter()); - + KisOpenGLCanvas2 *canvasWidget = new KisOpenGLCanvas2(this, m_d->coordinatesConverter, 0, m_d->view->image(), m_d->displayColorConverter); setCanvasWidget(canvasWidget); - -#else - qFatal("Bad use of createOpenGLCanvas(). It shouldn't have happened =("); -#endif } void KisCanvas2::createCanvas(bool useOpenGL) @@ -416,21 +387,18 @@ createOpenGLCanvas(); if (cfg.canvasState() == "OPENGL_FAILED") { // Creating the opengl canvas failed, fall back + warnKrita << "OpenGL Canvas initialization returned OPENGL_FAILED. Falling back to QPainter."; createQPainterCanvas(); } } else { warnKrita << "Tried to create OpenGL widget when system doesn't have OpenGL\n"; createQPainterCanvas(); } #else - warnKrita << "OpenGL requested while it's not available, starting qpainter canvas"; + warnKrita << "User requested an OpenGL canvas, but Krita was compiled without OpenGL support. Falling back to QPainter."; createQPainterCanvas(); #endif } else { -#ifdef HAVE_OPENGL - // Free shared pointer - m_d->openGLImageTextures = 0; -#endif createQPainterCanvas(); } if (m_d->popupPalette) { @@ -469,15 +437,7 @@ void KisCanvas2::disconnectCurrentCanvas() { - if (m_d->currentCanvasIsOpenGL) { -#ifdef HAVE_OPENGL - Q_ASSERT(m_d->openGLImageTextures); - m_d->openGLImageTextures->disconnect(this); - m_d->openGLImageTextures->disconnect(m_d->view->image()); -#else - qFatal("Bad use of disconnectCurrentCanvas(). It shouldn't have happened =("); -#endif - } + m_d->canvasWidget->disconnectCurrentCanvas(); } void KisCanvas2::resetCanvas(bool useOpenGL) @@ -527,40 +487,13 @@ void KisCanvas2::setDisplayFilter(KisDisplayFilter *displayFilter) { m_d->displayColorConverter->setDisplayFilter(displayFilter); + KisImageWSP image = this->image(); - if (m_d->currentCanvasIsOpenGL) { -#ifdef HAVE_OPENGL - KisImageWSP image = this->image(); - image->barrierLock(); - - bool needsInternalColorManagement = - !displayFilter || displayFilter->useInternalColorManagement(); - - bool needsFullRefresh = - m_d->openGLImageTextures-> - setInternalColorManagementActive(needsInternalColorManagement); - - m_d->canvasWidget->setDisplayFilter(displayFilter); - - if (needsFullRefresh) { - startUpdateInPatches(image->bounds()); - } else { - updateCanvas(); - } - - image->unlock(); -#endif - } - else { - KisImageWSP image = this->image(); - image->barrierLock(); + image->barrierLock(); - Q_ASSERT(m_d->prescaledProjection); - m_d->prescaledProjection->setDisplayFilter(displayFilter); - startUpdateInPatches(image->bounds()); + m_d->canvasWidget->setDisplayFilter(displayFilter); - image->unlock(); - } + image->unlock(); } KisDisplayFilter *KisCanvas2::displayFilter() const @@ -597,87 +530,29 @@ void KisCanvas2::finishResizingImage(qint32 w, qint32 h) { - if (m_d->currentCanvasIsOpenGL) { -#ifdef HAVE_OPENGL - Q_ASSERT(m_d->openGLImageTextures); - m_d->openGLImageTextures->slotImageSizeChanged(w, h); -#else - Q_ASSERT_X(0, "finishResizingImage()", "Bad use of finishResizingImage(). It shouldn't have happened =("); -#endif - } else { - Q_ASSERT(m_d->prescaledProjection); - m_d->prescaledProjection->slotImageSizeChanged(w, h); - } + m_d->canvasWidget->finishResizingImage(w, h); } void KisCanvas2::startUpdateCanvasProjection(const QRect & rc) { - KisUpdateInfoSP info; - - if (m_d->currentCanvasIsOpenGL) { -#ifdef HAVE_OPENGL - Q_ASSERT(m_d->openGLImageTextures); - m_d->openGLImageTextures->setChannelFlags(m_d->channelFlags); - info = m_d->openGLImageTextures->updateCache(rc); -#else - Q_ASSERT_X(0, "startUpdateCanvasProjection()", "Bad use of startUpdateCanvasProjection(). It shouldn't have happened =("); -#endif - } else { - Q_ASSERT(m_d->prescaledProjection); - info = m_d->prescaledProjection->updateCache(rc); - } - + KisUpdateInfoSP info = m_d->canvasWidget->startUpdateCanvasProjection(rc, m_d->channelFlags); if (m_d->projectionUpdatesCompressor.putUpdateInfo(info)) { emit sigCanvasCacheUpdated(); } - } void KisCanvas2::updateCanvasProjection() { - KisUpdateInfoSP info; - - while (info = m_d->projectionUpdatesCompressor.takeUpdateInfo()) { - - /** - * It might happen that the canvas type is switched while the - * update info is being stuck in the Qt's signals queue. Than a wrong - * type of the info may come. So just check it here. - */ -#ifdef HAVE_OPENGL - bool isOpenGLUpdateInfo = dynamic_cast(info.data()); - if (isOpenGLUpdateInfo != m_d->currentCanvasIsOpenGL) - continue; -#endif - - if (m_d->currentCanvasIsOpenGL) { -#ifdef HAVE_OPENGL - - Q_ASSERT(m_d->openGLImageTextures); - m_d->openGLImageTextures->recalculateCache(info); - - /** - * FIXME: Please not update entire canvas - * Implement info->dirtyViewportRect() - */ - updateCanvasWidgetImpl(); -#else - Q_ASSERT_X(0, "updateCanvasProjection()", "Bad use of updateCanvasProjection(). It shouldn't have happened =("); -#endif + while (KisUpdateInfoSP info = m_d->projectionUpdatesCompressor.takeUpdateInfo()) { + QRect vRect = m_d->canvasWidget->updateCanvasProjection(info); + if (!vRect.isEmpty()) { + updateCanvasWidgetImpl(m_d->coordinatesConverter->viewportToWidget(vRect).toAlignedRect()); } - else { - // See comment in startUpdateCanvasProjection() - Q_ASSERT(m_d->prescaledProjection); - - m_d->prescaledProjection->recalculateCache(info); - - QRect vRect = m_d->coordinatesConverter-> - viewportToWidget(info->dirtyViewportRect()).toAlignedRect(); + } - if (!vRect.isEmpty()) { - updateCanvasWidgetImpl(vRect); - } - } + // TODO: Implement info->dirtyViewportRect() for KisOpenGLCanvas2 to avoid updating whole canvas + if (m_d->currentCanvasIsOpenGL) { + updateCanvasWidgetImpl(); } } @@ -819,21 +694,7 @@ image->barrierLock(); - if (m_d->currentCanvasIsOpenGL) { -#ifdef HAVE_OPENGL - Q_ASSERT(m_d->openGLImageTextures); - m_d->openGLImageTextures->setMonitorProfile(m_d->displayColorConverter->monitorProfile(), - m_d->displayColorConverter->renderingIntent(), - m_d->displayColorConverter->conversionFlags()); -#else - Q_ASSERT_X(0, "KisCanvas2::setMonitorProfile", "Bad use of setMonitorProfile(). It shouldn't have happened =("); -#endif - } else { - Q_ASSERT(m_d->prescaledProjection); - m_d->prescaledProjection->setMonitorProfile(m_d->displayColorConverter->monitorProfile(), - m_d->displayColorConverter->renderingIntent(), - m_d->displayColorConverter->conversionFlags()); - } + m_d->canvasWidget->setDisplayProfile(m_d->displayColorConverter); startUpdateInPatches(image->bounds()); @@ -941,5 +802,3 @@ KisCanvasDecoration* deco = decoration("paintingAssistantsDecoration"); return qobject_cast(deco); } - - diff --git a/krita/ui/canvas/kis_qpainter_canvas.h b/krita/ui/canvas/kis_qpainter_canvas.h --- a/krita/ui/canvas/kis_qpainter_canvas.h +++ b/krita/ui/canvas/kis_qpainter_canvas.h @@ -23,11 +23,13 @@ #include "kis_canvas_widget_base.h" #include "kis_prescaled_projection.h" +#include "kis_ui_types.h" class QImage; class QPaintEvent; class QPainter; class KisCanvas2; +class KisDisplayColorConverter; /** * @@ -51,21 +53,25 @@ void setPrescaledProjection(KisPrescaledProjectionSP prescaledProjection); -public: // QWidget +public: // QWidget overrides - /// reimplemented method from superclass void paintEvent(QPaintEvent * ev); - /// reimplemented method from superclass void resizeEvent(QResizeEvent *e); - /// reimplemented method from superclass virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; - /// reimplemented method from superclass virtual void inputMethodEvent(QInputMethodEvent *event); -public: // KisAbstractCanvasWidget +public: // Implement kis_abstract_canvas_widget interface + void setDisplayFilter(KisDisplayFilter* displayFilter); + void setWrapAroundViewingMode(bool value); + void channelSelectionChanged(QBitArray channelFlags); + void setDisplayProfile(KisDisplayColorConverter *colorConverter); + void disconnectCurrentCanvas(); + void finishResizingImage(qint32 w, qint32 h); + KisUpdateInfoSP startUpdateCanvasProjection(const QRect & rc, QBitArray channelFlags); + QRect updateCanvasProjection(KisUpdateInfoSP info); QWidget * widget() { return this; diff --git a/krita/ui/canvas/kis_qpainter_canvas.cpp b/krita/ui/canvas/kis_qpainter_canvas.cpp --- a/krita/ui/canvas/kis_qpainter_canvas.cpp +++ b/krita/ui/canvas/kis_qpainter_canvas.cpp @@ -53,8 +53,10 @@ #include "kis_selection_manager.h" #include "kis_selection.h" #include "kis_perspective_grid_manager.h" +#include "kis_canvas_updates_compressor.h" #include "kis_config_notifier.h" #include "kis_group_layer.h" +#include "canvas/kis_display_color_converter.h" //#define DEBUG_REPAINT #include @@ -164,6 +166,68 @@ processInputMethodEvent(event); } +void KisQPainterCanvas::channelSelectionChanged(QBitArray channelFlags) +{ + Q_ASSERT(m_d->prescaledProjection); + m_d->prescaledProjection->setChannelFlags(channelFlags); +} + +void KisQPainterCanvas::setDisplayProfile(KisDisplayColorConverter *colorConverter) +{ + Q_ASSERT(m_d->prescaledProjection); + m_d->prescaledProjection->setMonitorProfile(colorConverter->monitorProfile(), + colorConverter->renderingIntent(), + colorConverter->conversionFlags()); +} + +void KisQPainterCanvas::setDisplayFilter(KisDisplayFilter* displayFilter) +{ + Q_ASSERT(m_d->prescaledProjection); + m_d->prescaledProjection->setDisplayFilter(displayFilter); + + startUpdateInPatches(image->bounds()); +} + + +void KisQPainterCanvas::setWrapAroundViewingMode(bool value) +{ + kDebug() << "Wrap around viewing mode not implemented in QPainter Canvas."; + return; +} + +void KisQPainterCanvas::disconnectCurrentCanvas() +{ } + +void KisQPainterCanvas::finishResizingImage(qint32 w, qint32 h) +{ + m_d->prescaledProjection->slotImageSizeChanged(w, h); +} + +KisUpdateInfoSP KisQPainterCanvas::startUpdateCanvasProjection(const QRect & rc, QBitArray channelFlags) +{ + Q_UNUSED(channelFlags); + + return m_d->prescaledProjection->updateCache(rc); +} + + +QRect KisQPainterCanvas::updateCanvasProjection(KisUpdateInfoSP info) +{ + /** + * It might happen that the canvas type is switched while the + * update info is being stuck in the Qt's signals queue. Than a wrong + * type of the info may come. So just check it here. + */ + bool isPPUpdateInfo = dynamic_cast(info.data()); + if (isPPUpdateInfo) { + m_d->prescaledProjection->recalculateCache(info); + return info->dirtyViewportRect(); + } else { + return QRect(); + } +} + + void KisQPainterCanvas::resizeEvent(QResizeEvent *e) { QSize size(e->size()); @@ -188,4 +252,3 @@ { return focusNextPrevChild(next); } - diff --git a/krita/ui/opengl/kis_opengl_canvas2.h b/krita/ui/opengl/kis_opengl_canvas2.h --- a/krita/ui/opengl/kis_opengl_canvas2.h +++ b/krita/ui/opengl/kis_opengl_canvas2.h @@ -1,5 +1,6 @@ - /* +/* * Copyright (C) Boudewijn Rempt , (C) 2006 + * Copyright (C) Michael Abrahams , (C) 2015 * * 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 @@ -32,10 +33,12 @@ #include "opengl/kis_opengl_image_textures.h" #include "kritaui_export.h" +#include "kis_ui_types.h" class QWidget; class QPaintEvent; class KisCanvas2; +class KisDisplayColorConverter; /** @@ -52,61 +55,59 @@ public: - KisOpenGLCanvas2(KisCanvas2 * canvas, KisCoordinatesConverter *coordinatesConverter, QWidget * parent, KisOpenGLImageTexturesSP imageTextures); + KisOpenGLCanvas2(KisCanvas2 *canvas, KisCoordinatesConverter *coordinatesConverter, QWidget *parent, KisImageWSP image, KisDisplayColorConverter *colorConverter); virtual ~KisOpenGLCanvas2(); - void setDisplayFilter(KisDisplayFilter* displayFilter); - void setWrapAroundViewingMode(bool value); +public: // QOpenGLWidget -public: // QWidget + void resizeGL(int width, int height); + void initializeGL(); + void paintGL(); virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; virtual void inputMethodEvent(QInputMethodEvent *event); public: - - bool isBusy() const; void initializeCheckerShader(); void initializeDisplayShader(); void renderCanvasGL(); void renderDecorations(QPainter *painter); - -private Q_SLOTS: - void slotConfigChanged(); - - -public: - - void resizeGL(int width, int height); - void initializeGL(); - void paintGL(); - -public: +public: // Implement kis_abstract_canvas_widget interface + void setDisplayFilter(KisDisplayFilter* displayFilter); + void setWrapAroundViewingMode(bool value); + void channelSelectionChanged(QBitArray channelFlags); + void setDisplayProfile(KisDisplayColorConverter *colorConverter); + void disconnectCurrentCanvas(); + void finishResizingImage(qint32 w, qint32 h); + KisUpdateInfoSP startUpdateCanvasProjection(const QRect & rc, QBitArray channelFlags); + QRect updateCanvasProjection(KisUpdateInfoSP info); QWidget *widget() { return this; } + bool isBusy() const; + +private Q_SLOTS: + void slotConfigChanged(); + protected: // KisCanvasWidgetBase virtual bool callFocusNextPrevChild(bool next); private: void reportShaderLinkFailedAndExit(bool result, const QString &context, const QString &log); + void drawImage(); + void drawCheckers(); + QByteArray buildFragmentShader(); private: - - struct Private; Private * const d; - void drawImage(); - void drawCheckers(); - QByteArray buildFragmentShader(); - }; #endif // HAVE_OPENGL diff --git a/krita/ui/opengl/kis_opengl_canvas2.cpp b/krita/ui/opengl/kis_opengl_canvas2.cpp --- a/krita/ui/opengl/kis_opengl_canvas2.cpp +++ b/krita/ui/opengl/kis_opengl_canvas2.cpp @@ -1,5 +1,6 @@ /* This file is part of the KDE project * Copyright (C) Boudewijn Rempt , (C) 2006-2013 + * Copyright (C) 2015 Michael Abrahams * * 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 @@ -61,6 +62,7 @@ #include "opengl/kis_opengl_canvas2_p.h" #include "kis_coordinates_converter.h" #include "canvas/kis_display_filter.h" +#include "canvas/kis_display_color_converter.h" #define NEAR_VAL -1000.0 #define FAR_VAL 1000.0 @@ -157,7 +159,7 @@ }; -KisOpenGLCanvas2::KisOpenGLCanvas2(KisCanvas2 *canvas, KisCoordinatesConverter *coordinatesConverter, QWidget *parent, KisOpenGLImageTexturesSP imageTextures) +KisOpenGLCanvas2::KisOpenGLCanvas2(KisCanvas2 *canvas, KisCoordinatesConverter *coordinatesConverter, QWidget *parent, KisImageWSP image, KisDisplayColorConverter *colorConverter) : QOpenGLWidget(parent) , KisCanvasWidgetBase(canvas, coordinatesConverter) , d(new Private()) @@ -170,8 +172,10 @@ KisConfig cfg; cfg.writeEntry("canvasState", "OPENGL_STARTED"); - d->openGLImageTextures = imageTextures; - + d->openGLImageTextures = KisOpenGLImageTextures::getImageTextures(image, + colorConverter->monitorProfile(), + colorConverter->renderingIntent(), + colorConverter->conversionFlags()); setAcceptDrops(true); setFocusPolicy(Qt::StrongFocus); setAttribute(Qt::WA_NoSystemBackground); @@ -181,6 +185,8 @@ setAttribute(Qt::WA_InputMethodEnabled, true); setAttribute(Qt::WA_DontCreateNativeAncestors, true); + setDisplayFilter(colorConverter->displayFilter()); + connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged())); slotConfigChanged(); cfg.writeEntry("canvasState", "OPENGL_SUCCESS"); @@ -193,15 +199,37 @@ void KisOpenGLCanvas2::setDisplayFilter(KisDisplayFilter* displayFilter) { + + bool needsInternalColorManagement = + !displayFilter || displayFilter->useInternalColorManagement(); + + bool needsFullRefresh = + d->openGLImageTextures-> + setInternalColorManagementActive(needsInternalColorManagement); + d->displayFilter = displayFilter; if (d->canvasInitialized) { d->canvasInitialized = false; initializeDisplayShader(); initializeCheckerShader(); d->canvasInitialized = true; } + + if (needsFullRefresh) { + startUpdateInPatches(image->bounds()); + } else { + updateCanvas(); + } } +void KisOpenGLCanvas2::disconnectCurrentCanvas() +{ + Q_ASSERT(d->openGLImageTextures); + d->openGLImageTextures->disconnect(canvas()); + d->openGLImageTextures->disconnect(canvas()->image()); +} + + void KisOpenGLCanvas2::setWrapAroundViewingMode(bool value) { d->wrapAroundMode = value; @@ -707,6 +735,42 @@ drawDecorations(*painter, boundingRect); } + +void KisOpenGLCanvas2::setDisplayProfile(KisDisplayColorConverter *colorConverter) +{ + d->openGLImageTextures->setMonitorProfile(colorConverter->monitorProfile(), + colorConverter->renderingIntent(), + colorConverter->conversionFlags()); +} + +void KisOpenGLCanvas2::channelSelectionChanged(QBitArray channelFlags) +{ + d->openGLImageTextures->setChannelFlags(channelFlags); +} + + +void KisOpenGLCanvas2::finishResizingImage(qint32 w, qint32 h) +{ + d->openGLImageTextures->slotImageSizeChanged(w, h); +} + +KisUpdateInfoSP KisOpenGLCanvas2::startUpdateCanvasProjection(const QRect & rc, QBitArray channelFlags) +{ + d->openGLImageTextures->setChannelFlags(channelFlags); + return d->openGLImageTextures->updateCache(rc); +} + + +QRect KisOpenGLCanvas2::updateCanvasProjection(KisUpdateInfoSP info) +{ + // See KisQPainterCanvas::updateCanvasProjection for more info + bool isOpenGLUpdateInfo = dynamic_cast(info.data()); + if (isOpenGLUpdateInfo) { + d->openGLImageTextures->recalculateCache(info); + } + return QRect(); // FIXME: Implement dirty rect for OpenGL +} + bool KisOpenGLCanvas2::callFocusNextPrevChild(bool next) { return focusNextPrevChild(next);