Skip to content

Commit

Permalink
Add NemoBluredImage item
Browse files Browse the repository at this point in the history
  • Loading branch information
neochapay committed Sep 15, 2021
1 parent 352523a commit 518f282
Show file tree
Hide file tree
Showing 7 changed files with 426 additions and 1 deletion.
158 changes: 158 additions & 0 deletions examples/touch/content/BlurredImagePage.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Copyright (C) 2021 Chupligin Sergey (NeoChapay) <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

import QtQuick 2.6
import QtQuick.Controls 1.0 //needed for the Stack attached property
import QtQuick.Controls.Nemo 1.0
import QtQuick.Controls.Styles.Nemo 1.0

Page {
id: root

headerTools: HeaderToolsLayout {
showBackButton: false;
title: qsTr("Blurred page")
}



ScrollDecorator{
flickable: mainContent
}


Flickable{
id: mainContent
width: parent.width
height: parent.height

contentHeight: contentColumn.height+Theme.itemHeightExtraLarge

Column {
id: contentColumn
spacing: Theme.itemSpacingLarge*2
width: parent.width

anchors{
top: parent.top
topMargin: Theme.itemSpacingLarge
left: parent.left
leftMargin: Theme.itemSpacingLarge
}

NemoBlurredImage{
id: blurred
width: parent.width - Theme.itemSpacingLarge*2
height: root.height/3

source: "/usr/share/glacier-components/images/example.jpg"
}

Label {
text: qsTr("Select dim color")
}

Row{
width: parent.width - Theme.itemSpacingLarge*2
height: Theme.itemHeightExtraLarge

Rectangle{
width: parent.width/3
height: parent.height
color: "red"
Label{
anchors.fill: parent
text: "Red"
}

MouseArea{
anchors.fill: parent
onClicked: blurred.dimColor = "red"
}
}


Rectangle{
width: parent.width/3
height: parent.height
color: "black"
Label{
anchors.fill: parent
text: "Black"
}

MouseArea{
anchors.fill: parent
onClicked: blurred.dimColor = "black"
}
}

Rectangle{
width: parent.width/3
height: parent.height
color: "white"
Label{
anchors.fill: parent
text: "White"
color: "black"
}

MouseArea{
anchors.fill: parent
onClicked: blurred.dimColor = "white"
}
}
}

Label {
text: qsTr("Blur radius")
}

Slider {
id: radiusSlider
anchors.margins: 20
minimumValue: 0
maximumValue: 100
value: blurred.radius
width: parent.width - Theme.itemSpacingLarge*2
onValueChanged: {
blurred.radius = radiusSlider.value
}
}


Label {
text: qsTr("Opacity")
}

Slider {
id: opacitySlider
anchors.margins: 20
value: blurred.opacity
minimumValue: 0
maximumValue: 1
width: parent.width - Theme.itemSpacingLarge*2
onValueChanged: {
blurred.opacity = opacitySlider.value
}
}
}
}
}

4 changes: 4 additions & 0 deletions examples/touch/glacier-components.qml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ ApplicationWindow {
title: qsTr("Icons")
page: "content/IconPage.qml"
}
ListElement {
title: qsTr("Blurred images")
page: "content/BlurredImagePage.qml"
}
ListElement {
title: qsTr("Notifications")
page: "content/NotificationsPage.qml"
Expand Down
3 changes: 2 additions & 1 deletion examples/touch/touch.pro
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ qml.files += \
content/TimePickerPage.qml \
content/NotificationsPage.qml \
content/StatusNotifyPage.qml \
content/RingIndicatorPage.qml
content/RingIndicatorPage.qml \
content/BlurredImagePage.qml

qml.path = /usr/share/glacier-components/qml/content

Expand Down
2 changes: 2 additions & 0 deletions src/controls/controls.pro
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ OTHER_FILES += qmldir \
$$QML_FILES

HEADERS += \
nemoblurredimage.h \
qquicknemocontrolsextensionplugin.h \
hacks.h \
nemowindow.h \
Expand All @@ -58,6 +59,7 @@ HEADERS += \
nemofocussingleton.h

SOURCES += \
nemoblurredimage.cpp \
qquicknemocontrolsextensionplugin.cpp \
hacks.cpp \
nemowindow.cpp \
Expand Down
181 changes: 181 additions & 0 deletions src/controls/nemoblurredimage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* Copyright (C) 2021 Chupligin Sergey (NeoChapay) <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#include "nemoblurredimage.h"
#include "theme.h"

NemoBlurredImage::NemoBlurredImage(QQuickItem *parent)
:QQuickPaintedItem(parent)
, m_source("")
, m_fillMode(FillMode::Stretch)
, m_radius(50)
, m_opacity(0.5)
, m_dimColor(Qt::black)
{

}

void NemoBlurredImage::paint(QPainter *painter)
{
QSizeF itemSize = size();
QRectF target(0, 0, itemSize.width(), itemSize.height());
QImage source(m_source);

QImage blurr = makeBlurred(source, source.rect(), m_radius);
Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio;

if(m_fillMode == FillMode::PreserveAspectFit) {
aspectMode = Qt::KeepAspectRatio;
}

if(m_fillMode == FillMode::PreserveAspectCrop) {
aspectMode = Qt::KeepAspectRatioByExpanding;
}


blurr = blurr.scaled(QSize(itemSize.width(), itemSize.height()), aspectMode);

painter->drawImage(blurr.rect(), blurr);

painter->setBrush(QBrush(m_dimColor));
painter->setOpacity(m_opacity);
painter->drawRect(blurr.rect());
}

void NemoBlurredImage::setSource(QString path)
{
if(path == m_source) {
return;
}

QFile imgFile(path);
if(!imgFile.exists()) {
qWarning() << "Not exists!!!" << path;
return;
}

m_source = path;
emit sourceChanged();
update();
}

void NemoBlurredImage::setRadius(int radius)
{
if(radius != m_radius) {
m_radius = radius;
emit radiusChanged();
update();
}
}

void NemoBlurredImage::setOpacity(qreal opacity)
{
if(opacity != m_opacity) {
m_opacity = opacity;
emit opacityChanged();
update();
}
}

void NemoBlurredImage::setDimColor(QColor dimColor)
{
if(dimColor != m_dimColor) {
m_dimColor = dimColor;
emit dimColorChanged();
update();
}
}

void NemoBlurredImage::setFillMode(FillMode mode)
{
if(mode != m_fillMode) {
m_fillMode = mode;
emit fillModeChanged();
update();
}
}

QImage NemoBlurredImage::makeBlurred(QImage& image, const QRect& rect, int radius, bool alphaOnly)
{
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];

QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
int r1 = rect.top();
int r2 = rect.bottom();
int c1 = rect.left();
int c2 = rect.right();

int bpl = result.bytesPerLine();
int rgba[4];
unsigned char* p;

int i1 = 0;
int i2 = 3;

if (alphaOnly) {
i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
}

for (int col = c1; col <= c2; col++) {
p = result.scanLine(r1) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;

p += bpl;
for (int j = r1; j < r2; j++, p += bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}

for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c1 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;

p += 4;
for (int j = c1; j < c2; j++, p += 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}

for (int col = c1; col <= c2; col++) {
p = result.scanLine(r2) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;

p -= bpl;
for (int j = r1; j < r2; j++, p -= bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}

for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c2 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;

p -= 4;
for (int j = c1; j < c2; j++, p -= 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
}

return result;
}
Loading

0 comments on commit 518f282

Please sign in to comment.