You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
7.1 KiB
219 lines
7.1 KiB
/******************************************************************** |
|
KWin - the KDE window manager |
|
This file is part of the KDE project. |
|
|
|
Copyright (C) 2011, 2014 Martin Gräßlin <mgraesslin@kde.org> |
|
|
|
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 |
|
the Free Software Foundation; either version 2 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
*********************************************************************/ |
|
|
|
#include "thumbnailitem.h" |
|
// Qt |
|
#include <QStandardPaths> |
|
#include <QQuickWindow> |
|
#include <QSGSimpleTextureNode> |
|
|
|
namespace KWin |
|
{ |
|
|
|
BrightnessSaturationShader::BrightnessSaturationShader() |
|
: QSGMaterialShader() |
|
, m_id_matrix(0) |
|
, m_id_opacity(0) |
|
, m_id_saturation(0) |
|
, m_id_brightness(0) |
|
{ |
|
} |
|
|
|
const char *BrightnessSaturationShader::vertexShader() const |
|
{ |
|
return |
|
"attribute highp vec4 vertex; \n" |
|
"attribute highp vec2 texCoord; \n" |
|
"uniform highp mat4 u_matrix; \n" |
|
"varying highp vec2 v_coord; \n" |
|
"void main() { \n" |
|
" v_coord = texCoord; \n" |
|
" gl_Position = u_matrix * vertex; \n" |
|
"}"; |
|
} |
|
|
|
const char *BrightnessSaturationShader::fragmentShader() const |
|
{ |
|
return |
|
"uniform sampler2D qt_Texture; \n" |
|
"uniform lowp float u_opacity; \n" |
|
"uniform highp float u_saturation; \n" |
|
"uniform highp float u_brightness; \n" |
|
"varying highp vec2 v_coord; \n" |
|
"void main() { \n" |
|
" lowp vec4 tex = texture2D(qt_Texture, v_coord); \n" |
|
" if (u_saturation != 1.0) { \n" |
|
" tex.rgb = mix(vec3(dot( vec3( 0.30, 0.59, 0.11 ), tex.rgb )), tex.rgb, u_saturation); \n" |
|
" } \n" |
|
" tex.rgb = tex.rgb * u_brightness; \n" |
|
" gl_FragColor = tex * u_opacity; \n" |
|
"}"; |
|
} |
|
|
|
const char* const *BrightnessSaturationShader::attributeNames() const |
|
{ |
|
static char const *const names[] = { "vertex", "texCoord", 0 }; |
|
return names; |
|
} |
|
|
|
void BrightnessSaturationShader::updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) |
|
{ |
|
Q_ASSERT(program()->isLinked()); |
|
if (state.isMatrixDirty()) |
|
program()->setUniformValue(m_id_matrix, state.combinedMatrix()); |
|
if (state.isOpacityDirty()) |
|
program()->setUniformValue(m_id_opacity, state.opacity()); |
|
|
|
auto *tx = static_cast<BrightnessSaturationMaterial *>(newMaterial); |
|
auto *oldTx = static_cast<BrightnessSaturationMaterial *>(oldMaterial); |
|
QSGTexture *t = tx->texture(); |
|
t->setFiltering(QSGTexture::Linear); |
|
|
|
if (!oldTx || oldTx->texture()->textureId() != t->textureId()) |
|
t->bind(); |
|
else |
|
t->updateBindOptions(); |
|
|
|
program()->setUniformValue(m_id_saturation, static_cast<float>(tx->saturation)); |
|
program()->setUniformValue(m_id_brightness, static_cast<float>(tx->brightness)); |
|
} |
|
|
|
void BrightnessSaturationShader::initialize() |
|
{ |
|
QSGMaterialShader::initialize(); |
|
m_id_matrix = program()->uniformLocation("u_matrix"); |
|
m_id_opacity = program()->uniformLocation("u_opacity"); |
|
m_id_saturation = program()->uniformLocation("u_saturation"); |
|
m_id_brightness = program()->uniformLocation("u_brightness"); |
|
} |
|
|
|
WindowThumbnailItem::WindowThumbnailItem(QQuickItem* parent) |
|
: QQuickItem(parent) |
|
, m_wId(0) |
|
, m_image() |
|
, m_clipToItem(nullptr) |
|
, m_brightness(1.0) |
|
, m_saturation(1.0) |
|
{ |
|
setFlag(ItemHasContents); |
|
} |
|
|
|
WindowThumbnailItem::~WindowThumbnailItem() |
|
{ |
|
} |
|
|
|
void WindowThumbnailItem::setWId(qulonglong wId) |
|
{ |
|
m_wId = wId; |
|
emit wIdChanged(wId); |
|
findImage(); |
|
} |
|
|
|
void WindowThumbnailItem::setClipTo(QQuickItem *clip) |
|
{ |
|
if (m_clipToItem == clip) { |
|
return; |
|
} |
|
m_clipToItem = clip; |
|
emit clipToChanged(); |
|
} |
|
|
|
void WindowThumbnailItem::findImage() |
|
{ |
|
QString imagePath; |
|
switch (m_wId) { |
|
case Konqueror: |
|
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/konqueror.png"); |
|
break; |
|
case Systemsettings: |
|
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/systemsettings.png"); |
|
break; |
|
case KMail: |
|
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/kmail.png"); |
|
break; |
|
case Dolphin: |
|
imagePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/dolphin.png"); |
|
break; |
|
default: |
|
// ignore |
|
break; |
|
} |
|
if (imagePath.isNull()) { |
|
m_image = QImage(); |
|
} else { |
|
m_image = QImage(imagePath); |
|
} |
|
} |
|
|
|
QSGNode *WindowThumbnailItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) |
|
{ |
|
Q_UNUSED(updatePaintNodeData) |
|
QSGGeometryNode *node = static_cast<QSGGeometryNode*>(oldNode); |
|
if (!node) { |
|
node = new QSGGeometryNode(); |
|
auto *material = new BrightnessSaturationMaterial; |
|
material->setFlag(QSGMaterial::Blending); |
|
material->setTexture(window()->createTextureFromImage(m_image)); |
|
node->setMaterial(material); |
|
QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); |
|
node->setGeometry(geometry); |
|
} |
|
auto *material = static_cast<BrightnessSaturationMaterial*>(node->material()); |
|
const QSize size(material->texture()->textureSize().scaled(boundingRect().size().toSize(), Qt::KeepAspectRatio)); |
|
const qreal x = boundingRect().x() + (boundingRect().width() - size.width())/2; |
|
const qreal y = boundingRect().y() + (boundingRect().height() - size.height())/2; |
|
QSGGeometry::updateTexturedRectGeometry(node->geometry(), QRectF(QPointF(x, y), size), QRectF(0.0, 0.0, 1.0, 1.0)); |
|
material->brightness = m_brightness; |
|
material->saturation = m_saturation; |
|
node->markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial); |
|
return node; |
|
} |
|
|
|
qreal WindowThumbnailItem::brightness() const |
|
{ |
|
return m_brightness; |
|
} |
|
|
|
qreal WindowThumbnailItem::saturation() const |
|
{ |
|
return m_saturation; |
|
} |
|
|
|
void WindowThumbnailItem::setBrightness(qreal brightness) |
|
{ |
|
if (m_brightness == brightness) { |
|
return; |
|
} |
|
m_brightness = brightness; |
|
update(); |
|
emit brightnessChanged(); |
|
} |
|
|
|
void WindowThumbnailItem::setSaturation(qreal saturation) |
|
{ |
|
if (m_saturation == saturation) { |
|
return; |
|
} |
|
m_saturation = saturation; |
|
update(); |
|
emit saturationChanged(); |
|
} |
|
|
|
} // namespace KWin
|
|
|