1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation (qt-info@nokia.com)
|
---|
6 | **
|
---|
7 | ** This file is part of the QtDeclarative module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at qt-info@nokia.com.
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "private/qdeclarativeborderimage_p.h"
|
---|
43 | #include "private/qdeclarativeborderimage_p_p.h"
|
---|
44 |
|
---|
45 | #include <qdeclarativeinfo.h>
|
---|
46 | #include <private/qdeclarativeengine_p.h>
|
---|
47 |
|
---|
48 | #include <QNetworkRequest>
|
---|
49 | #include <QNetworkReply>
|
---|
50 | #include <QFile>
|
---|
51 |
|
---|
52 | QT_BEGIN_NAMESPACE
|
---|
53 |
|
---|
54 | /*!
|
---|
55 | \qmlclass BorderImage QDeclarativeBorderImage
|
---|
56 | \brief The BorderImage element provides an image that can be used as a border.
|
---|
57 | \inherits Item
|
---|
58 | \since 4.7
|
---|
59 | \ingroup qml-basic-visual-elements
|
---|
60 |
|
---|
61 | The BorderImage element is used to create borders out of images by scaling or tiling
|
---|
62 | parts of each image.
|
---|
63 |
|
---|
64 | A BorderImage element breaks a source image, specified using the \l url property,
|
---|
65 | into 9 regions, as shown below:
|
---|
66 |
|
---|
67 | \image declarative-scalegrid.png
|
---|
68 |
|
---|
69 | When the image is scaled, regions of the source image are scaled or tiled to
|
---|
70 | create the displayed border image in the following way:
|
---|
71 |
|
---|
72 | \list
|
---|
73 | \i The corners (regions 1, 3, 7, and 9) are not scaled at all.
|
---|
74 | \i Regions 2 and 8 are scaled according to
|
---|
75 | \l{BorderImage::horizontalTileMode}{horizontalTileMode}.
|
---|
76 | \i Regions 4 and 6 are scaled according to
|
---|
77 | \l{BorderImage::verticalTileMode}{verticalTileMode}.
|
---|
78 | \i The middle (region 5) is scaled according to both
|
---|
79 | \l{BorderImage::horizontalTileMode}{horizontalTileMode} and
|
---|
80 | \l{BorderImage::verticalTileMode}{verticalTileMode}.
|
---|
81 | \endlist
|
---|
82 |
|
---|
83 | The regions of the image are defined using the \l border property group, which
|
---|
84 | describes the distance from each edge of the source image to use as a border.
|
---|
85 |
|
---|
86 | \section1 Example Usage
|
---|
87 |
|
---|
88 | The following examples show the effects of the different modes on an image.
|
---|
89 | Guide lines are overlaid onto the image to show the different regions of the
|
---|
90 | image as described above.
|
---|
91 |
|
---|
92 | \beginfloatleft
|
---|
93 | \image qml-borderimage-normal-image.png
|
---|
94 | \endfloat
|
---|
95 |
|
---|
96 | An unscaled image is displayed using an Image element. The \l border property is
|
---|
97 | used to determine the parts of the image that will lie inside the unscaled corner
|
---|
98 | areas and the parts that will be stretched horizontally and vertically.
|
---|
99 |
|
---|
100 | \snippet doc/src/snippets/declarative/borderimage/normal-image.qml normal image
|
---|
101 |
|
---|
102 | \clearfloat
|
---|
103 | \beginfloatleft
|
---|
104 | \image qml-borderimage-scaled.png
|
---|
105 | \endfloat
|
---|
106 |
|
---|
107 | A BorderImage element is used to display the image, and it is given a size that is
|
---|
108 | larger than the original image. Since the \l horizontalTileMode property is set to
|
---|
109 | \l{BorderImage::horizontalTileMode}{BorderImage.Stretch}, the parts of image in
|
---|
110 | regions 2 and 8 are stretched horizontally. Since the \l verticalTileMode property
|
---|
111 | is set to \l{BorderImage::verticalTileMode}{BorderImage.Stretch}, the parts of image
|
---|
112 | in regions 4 and 6 are stretched vertically.
|
---|
113 |
|
---|
114 | \snippet doc/src/snippets/declarative/borderimage/borderimage-scaled.qml scaled border image
|
---|
115 |
|
---|
116 | \clearfloat
|
---|
117 | \beginfloatleft
|
---|
118 | \image qml-borderimage-tiled.png
|
---|
119 | \endfloat
|
---|
120 |
|
---|
121 | Again, a large BorderImage element is used to display the image. With the
|
---|
122 | \l horizontalTileMode property set to \l{BorderImage::horizontalTileMode}{BorderImage.Repeat},
|
---|
123 | the parts of image in regions 2 and 8 are tiled so that they fill the space at the
|
---|
124 | top and bottom of the element. Similarly, the \l verticalTileMode property is set to
|
---|
125 | \l{BorderImage::verticalTileMode}{BorderImage.Repeat}, the parts of image in regions
|
---|
126 | 4 and 6 are tiled so that they fill the space at the left and right of the element.
|
---|
127 |
|
---|
128 | \snippet doc/src/snippets/declarative/borderimage/borderimage-tiled.qml tiled border image
|
---|
129 |
|
---|
130 | \clearfloat
|
---|
131 | In some situations, the width of regions 2 and 8 may not be an exact multiple of the width
|
---|
132 | of the corresponding regions in the source image. Similarly, the height of regions 4 and 6
|
---|
133 | may not be an exact multiple of the height of the corresponding regions. It can be useful
|
---|
134 | to use \l{BorderImage::horizontalTileMode}{BorderImage.Round} instead of
|
---|
135 | \l{BorderImage::horizontalTileMode}{BorderImage.Repeat} in cases like these.
|
---|
136 |
|
---|
137 | The \l{declarative/imageelements/borderimage}{BorderImage example} shows how a BorderImage
|
---|
138 | can be used to simulate a shadow effect on a rectangular item.
|
---|
139 |
|
---|
140 | \section1 Quality and Performance
|
---|
141 |
|
---|
142 | By default, any scaled regions of the image are rendered without smoothing to improve
|
---|
143 | rendering speed. Setting the \l smooth property improves rendering quality of scaled
|
---|
144 | regions, but may slow down rendering.
|
---|
145 |
|
---|
146 | The source image may not be loaded instantaneously, depending on its original location.
|
---|
147 | Loading progress can be monitored with the \l progress property.
|
---|
148 |
|
---|
149 | \sa Image, AnimatedImage
|
---|
150 | */
|
---|
151 |
|
---|
152 | QDeclarativeBorderImage::QDeclarativeBorderImage(QDeclarativeItem *parent)
|
---|
153 | : QDeclarativeImageBase(*(new QDeclarativeBorderImagePrivate), parent)
|
---|
154 | {
|
---|
155 | }
|
---|
156 |
|
---|
157 | QDeclarativeBorderImage::~QDeclarativeBorderImage()
|
---|
158 | {
|
---|
159 | Q_D(QDeclarativeBorderImage);
|
---|
160 | if (d->sciReply)
|
---|
161 | d->sciReply->deleteLater();
|
---|
162 | }
|
---|
163 | /*!
|
---|
164 | \qmlproperty enumeration BorderImage::status
|
---|
165 |
|
---|
166 | This property describes the status of image loading. It can be one of:
|
---|
167 |
|
---|
168 | \list
|
---|
169 | \o BorderImage.Null - no image has been set
|
---|
170 | \o BorderImage.Ready - the image has been loaded
|
---|
171 | \o BorderImage.Loading - the image is currently being loaded
|
---|
172 | \o BorderImage.Error - an error occurred while loading the image
|
---|
173 | \endlist
|
---|
174 |
|
---|
175 | \sa progress
|
---|
176 | */
|
---|
177 |
|
---|
178 | /*!
|
---|
179 | \qmlproperty real BorderImage::progress
|
---|
180 |
|
---|
181 | This property holds the progress of image loading, from 0.0 (nothing loaded)
|
---|
182 | to 1.0 (finished).
|
---|
183 |
|
---|
184 | \sa status
|
---|
185 | */
|
---|
186 |
|
---|
187 | /*!
|
---|
188 | \qmlproperty bool BorderImage::smooth
|
---|
189 |
|
---|
190 | Set this property if you want the image to be smoothly filtered when scaled or
|
---|
191 | transformed. Smooth filtering gives better visual quality, but is slower. If
|
---|
192 | the image is displayed at its natural size, this property has no visual or
|
---|
193 | performance effect.
|
---|
194 |
|
---|
195 | By default, this property is set to false.
|
---|
196 |
|
---|
197 | \note Generally scaling artifacts are only visible if the image is stationary on
|
---|
198 | the screen. A common pattern when animating an image is to disable smooth
|
---|
199 | filtering at the beginning of the animation and enable it at the conclusion.
|
---|
200 | */
|
---|
201 |
|
---|
202 | /*!
|
---|
203 | \qmlproperty url BorderImage::source
|
---|
204 |
|
---|
205 | This property holds the URL that refers to the source image.
|
---|
206 |
|
---|
207 | BorderImage can handle any image format supported by Qt, loaded from any
|
---|
208 | URL scheme supported by Qt.
|
---|
209 |
|
---|
210 | It can also handle .sci files, which are a QML-specific format. A .sci
|
---|
211 | file uses a simple text-based format that specifies the borders, the
|
---|
212 | image file and the tile rules.
|
---|
213 |
|
---|
214 | The following .sci file sets the borders to 10 on each side for the
|
---|
215 | image \c picture.png:
|
---|
216 |
|
---|
217 | \qml
|
---|
218 | border.left: 10
|
---|
219 | border.top: 10
|
---|
220 | border.bottom: 10
|
---|
221 | border.right: 10
|
---|
222 | source: picture.png
|
---|
223 | \endqml
|
---|
224 |
|
---|
225 | The URL may be absolute, or relative to the URL of the component.
|
---|
226 |
|
---|
227 | \sa QDeclarativeImageProvider
|
---|
228 | */
|
---|
229 | void QDeclarativeBorderImage::setSource(const QUrl &url)
|
---|
230 | {
|
---|
231 | Q_D(QDeclarativeBorderImage);
|
---|
232 | //equality is fairly expensive, so we bypass for simple, common case
|
---|
233 | if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
|
---|
234 | return;
|
---|
235 |
|
---|
236 | if (d->sciReply) {
|
---|
237 | d->sciReply->deleteLater();
|
---|
238 | d->sciReply = 0;
|
---|
239 | }
|
---|
240 |
|
---|
241 | d->url = url;
|
---|
242 | d->sciurl = QUrl();
|
---|
243 | emit sourceChanged(d->url);
|
---|
244 |
|
---|
245 | if (isComponentComplete())
|
---|
246 | load();
|
---|
247 | }
|
---|
248 |
|
---|
249 | void QDeclarativeBorderImage::load()
|
---|
250 | {
|
---|
251 | Q_D(QDeclarativeBorderImage);
|
---|
252 | if (d->progress != 0.0) {
|
---|
253 | d->progress = 0.0;
|
---|
254 | emit progressChanged(d->progress);
|
---|
255 | }
|
---|
256 |
|
---|
257 | if (d->url.isEmpty()) {
|
---|
258 | d->pix.clear();
|
---|
259 | d->status = Null;
|
---|
260 | setImplicitWidth(0);
|
---|
261 | setImplicitHeight(0);
|
---|
262 | emit statusChanged(d->status);
|
---|
263 | update();
|
---|
264 | } else {
|
---|
265 | d->status = Loading;
|
---|
266 | if (d->url.path().endsWith(QLatin1String("sci"))) {
|
---|
267 | #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
|
---|
268 | QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
|
---|
269 | if (!lf.isEmpty()) {
|
---|
270 | QFile file(lf);
|
---|
271 | file.open(QIODevice::ReadOnly);
|
---|
272 | setGridScaledImage(QDeclarativeGridScaledImage(&file));
|
---|
273 | } else
|
---|
274 | #endif
|
---|
275 | {
|
---|
276 | QNetworkRequest req(d->url);
|
---|
277 | d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
|
---|
278 |
|
---|
279 | static int sciReplyFinished = -1;
|
---|
280 | static int thisSciRequestFinished = -1;
|
---|
281 | if (sciReplyFinished == -1) {
|
---|
282 | sciReplyFinished =
|
---|
283 | QNetworkReply::staticMetaObject.indexOfSignal("finished()");
|
---|
284 | thisSciRequestFinished =
|
---|
285 | QDeclarativeBorderImage::staticMetaObject.indexOfSlot("sciRequestFinished()");
|
---|
286 | }
|
---|
287 |
|
---|
288 | QMetaObject::connect(d->sciReply, sciReplyFinished, this,
|
---|
289 | thisSciRequestFinished, Qt::DirectConnection);
|
---|
290 | }
|
---|
291 | } else {
|
---|
292 |
|
---|
293 | d->pix.load(qmlEngine(this), d->url, d->async);
|
---|
294 |
|
---|
295 | if (d->pix.isLoading()) {
|
---|
296 | d->pix.connectFinished(this, SLOT(requestFinished()));
|
---|
297 | d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
|
---|
298 | } else {
|
---|
299 | QSize impsize = d->pix.implicitSize();
|
---|
300 | setImplicitWidth(impsize.width());
|
---|
301 | setImplicitHeight(impsize.height());
|
---|
302 |
|
---|
303 | if (d->pix.isReady()) {
|
---|
304 | d->status = Ready;
|
---|
305 | } else {
|
---|
306 | d->status = Error;
|
---|
307 | qmlInfo(this) << d->pix.error();
|
---|
308 | }
|
---|
309 |
|
---|
310 | d->progress = 1.0;
|
---|
311 | emit statusChanged(d->status);
|
---|
312 | emit progressChanged(d->progress);
|
---|
313 | update();
|
---|
314 | }
|
---|
315 | }
|
---|
316 | }
|
---|
317 |
|
---|
318 | emit statusChanged(d->status);
|
---|
319 | }
|
---|
320 |
|
---|
321 | /*!
|
---|
322 | \qmlproperty int BorderImage::border.left
|
---|
323 | \qmlproperty int BorderImage::border.right
|
---|
324 | \qmlproperty int BorderImage::border.top
|
---|
325 | \qmlproperty int BorderImage::border.bottom
|
---|
326 |
|
---|
327 | The 4 border lines (2 horizontal and 2 vertical) break the image into 9 sections,
|
---|
328 | as shown below:
|
---|
329 |
|
---|
330 | \image declarative-scalegrid.png
|
---|
331 |
|
---|
332 | Each border line (left, right, top, and bottom) specifies an offset in pixels
|
---|
333 | from the respective edge of the source image. By default, each border line has
|
---|
334 | a value of 0.
|
---|
335 |
|
---|
336 | For example, the following definition sets the bottom line 10 pixels up from
|
---|
337 | the bottom of the image:
|
---|
338 |
|
---|
339 | \qml
|
---|
340 | border.bottom: 10
|
---|
341 | \endqml
|
---|
342 |
|
---|
343 | The border lines can also be specified using a
|
---|
344 | \l {BorderImage::source}{.sci file}.
|
---|
345 | */
|
---|
346 |
|
---|
347 | QDeclarativeScaleGrid *QDeclarativeBorderImage::border()
|
---|
348 | {
|
---|
349 | Q_D(QDeclarativeBorderImage);
|
---|
350 | return d->getScaleGrid();
|
---|
351 | }
|
---|
352 |
|
---|
353 | /*!
|
---|
354 | \qmlproperty enumeration BorderImage::horizontalTileMode
|
---|
355 | \qmlproperty enumeration BorderImage::verticalTileMode
|
---|
356 |
|
---|
357 | This property describes how to repeat or stretch the middle parts of the border image.
|
---|
358 |
|
---|
359 | \list
|
---|
360 | \o BorderImage.Stretch - Scales the image to fit to the available area.
|
---|
361 | \o BorderImage.Repeat - Tile the image until there is no more space. May crop the last image.
|
---|
362 | \o BorderImage.Round - Like Repeat, but scales the images down to ensure that the last image is not cropped.
|
---|
363 | \endlist
|
---|
364 |
|
---|
365 | The default tile mode for each property is BorderImage.Stretch.
|
---|
366 | */
|
---|
367 | QDeclarativeBorderImage::TileMode QDeclarativeBorderImage::horizontalTileMode() const
|
---|
368 | {
|
---|
369 | Q_D(const QDeclarativeBorderImage);
|
---|
370 | return d->horizontalTileMode;
|
---|
371 | }
|
---|
372 |
|
---|
373 | void QDeclarativeBorderImage::setHorizontalTileMode(TileMode t)
|
---|
374 | {
|
---|
375 | Q_D(QDeclarativeBorderImage);
|
---|
376 | if (t != d->horizontalTileMode) {
|
---|
377 | d->horizontalTileMode = t;
|
---|
378 | emit horizontalTileModeChanged();
|
---|
379 | update();
|
---|
380 | }
|
---|
381 | }
|
---|
382 |
|
---|
383 | QDeclarativeBorderImage::TileMode QDeclarativeBorderImage::verticalTileMode() const
|
---|
384 | {
|
---|
385 | Q_D(const QDeclarativeBorderImage);
|
---|
386 | return d->verticalTileMode;
|
---|
387 | }
|
---|
388 |
|
---|
389 | void QDeclarativeBorderImage::setVerticalTileMode(TileMode t)
|
---|
390 | {
|
---|
391 | Q_D(QDeclarativeBorderImage);
|
---|
392 | if (t != d->verticalTileMode) {
|
---|
393 | d->verticalTileMode = t;
|
---|
394 | emit verticalTileModeChanged();
|
---|
395 | update();
|
---|
396 | }
|
---|
397 | }
|
---|
398 |
|
---|
399 | void QDeclarativeBorderImage::setGridScaledImage(const QDeclarativeGridScaledImage& sci)
|
---|
400 | {
|
---|
401 | Q_D(QDeclarativeBorderImage);
|
---|
402 | if (!sci.isValid()) {
|
---|
403 | d->status = Error;
|
---|
404 | emit statusChanged(d->status);
|
---|
405 | } else {
|
---|
406 | QDeclarativeScaleGrid *sg = border();
|
---|
407 | sg->setTop(sci.gridTop());
|
---|
408 | sg->setBottom(sci.gridBottom());
|
---|
409 | sg->setLeft(sci.gridLeft());
|
---|
410 | sg->setRight(sci.gridRight());
|
---|
411 | d->horizontalTileMode = sci.horizontalTileRule();
|
---|
412 | d->verticalTileMode = sci.verticalTileRule();
|
---|
413 |
|
---|
414 | d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
|
---|
415 |
|
---|
416 | d->pix.load(qmlEngine(this), d->sciurl, d->async);
|
---|
417 |
|
---|
418 | if (d->pix.isLoading()) {
|
---|
419 | static int thisRequestProgress = -1;
|
---|
420 | static int thisRequestFinished = -1;
|
---|
421 | if (thisRequestProgress == -1) {
|
---|
422 | thisRequestProgress =
|
---|
423 | QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
|
---|
424 | thisRequestFinished =
|
---|
425 | QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestFinished()");
|
---|
426 | }
|
---|
427 |
|
---|
428 | d->pix.connectFinished(this, thisRequestFinished);
|
---|
429 | d->pix.connectDownloadProgress(this, thisRequestProgress);
|
---|
430 |
|
---|
431 | } else {
|
---|
432 |
|
---|
433 | QSize impsize = d->pix.implicitSize();
|
---|
434 | setImplicitWidth(impsize.width());
|
---|
435 | setImplicitHeight(impsize.height());
|
---|
436 |
|
---|
437 | if (d->pix.isReady()) {
|
---|
438 | d->status = Ready;
|
---|
439 | } else {
|
---|
440 | d->status = Error;
|
---|
441 | qmlInfo(this) << d->pix.error();
|
---|
442 | }
|
---|
443 |
|
---|
444 | d->progress = 1.0;
|
---|
445 | emit statusChanged(d->status);
|
---|
446 | emit progressChanged(1.0);
|
---|
447 | update();
|
---|
448 |
|
---|
449 | }
|
---|
450 | }
|
---|
451 | }
|
---|
452 |
|
---|
453 | void QDeclarativeBorderImage::requestFinished()
|
---|
454 | {
|
---|
455 | Q_D(QDeclarativeBorderImage);
|
---|
456 |
|
---|
457 | QSize impsize = d->pix.implicitSize();
|
---|
458 | if (d->pix.isError()) {
|
---|
459 | d->status = Error;
|
---|
460 | qmlInfo(this) << d->pix.error();
|
---|
461 | } else {
|
---|
462 | d->status = Ready;
|
---|
463 | }
|
---|
464 |
|
---|
465 | setImplicitWidth(impsize.width());
|
---|
466 | setImplicitHeight(impsize.height());
|
---|
467 |
|
---|
468 | d->progress = 1.0;
|
---|
469 | emit statusChanged(d->status);
|
---|
470 | emit progressChanged(1.0);
|
---|
471 | update();
|
---|
472 | }
|
---|
473 |
|
---|
474 | #define BORDERIMAGE_MAX_REDIRECT 16
|
---|
475 |
|
---|
476 | void QDeclarativeBorderImage::sciRequestFinished()
|
---|
477 | {
|
---|
478 | Q_D(QDeclarativeBorderImage);
|
---|
479 |
|
---|
480 | d->redirectCount++;
|
---|
481 | if (d->redirectCount < BORDERIMAGE_MAX_REDIRECT) {
|
---|
482 | QVariant redirect = d->sciReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
|
---|
483 | if (redirect.isValid()) {
|
---|
484 | QUrl url = d->sciReply->url().resolved(redirect.toUrl());
|
---|
485 | setSource(url);
|
---|
486 | return;
|
---|
487 | }
|
---|
488 | }
|
---|
489 | d->redirectCount=0;
|
---|
490 |
|
---|
491 | if (d->sciReply->error() != QNetworkReply::NoError) {
|
---|
492 | d->status = Error;
|
---|
493 | d->sciReply->deleteLater();
|
---|
494 | d->sciReply = 0;
|
---|
495 | emit statusChanged(d->status);
|
---|
496 | } else {
|
---|
497 | QDeclarativeGridScaledImage sci(d->sciReply);
|
---|
498 | d->sciReply->deleteLater();
|
---|
499 | d->sciReply = 0;
|
---|
500 | setGridScaledImage(sci);
|
---|
501 | }
|
---|
502 | }
|
---|
503 |
|
---|
504 | void QDeclarativeBorderImage::doUpdate()
|
---|
505 | {
|
---|
506 | update();
|
---|
507 | }
|
---|
508 |
|
---|
509 | void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
|
---|
510 | {
|
---|
511 | Q_D(QDeclarativeBorderImage);
|
---|
512 | if (d->pix.isNull() || d->width() <= 0.0 || d->height() <= 0.0)
|
---|
513 | return;
|
---|
514 |
|
---|
515 | bool oldAA = p->testRenderHint(QPainter::Antialiasing);
|
---|
516 | bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
|
---|
517 | if (d->smooth)
|
---|
518 | p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
|
---|
519 |
|
---|
520 | const QDeclarativeScaleGrid *border = d->getScaleGrid();
|
---|
521 | int left = border->left();
|
---|
522 | int right = border->right();
|
---|
523 | qreal borderWidth = left + right;
|
---|
524 | if (borderWidth > 0.0 && d->width() < borderWidth) {
|
---|
525 | qreal diff = borderWidth - d->width() - 1;
|
---|
526 | left -= qRound(diff * qreal(left) / borderWidth);
|
---|
527 | right -= qRound(diff * qreal(right) / borderWidth);
|
---|
528 | }
|
---|
529 | int top = border->top();
|
---|
530 | int bottom = border->bottom();
|
---|
531 | qreal borderHeight = top + bottom;
|
---|
532 | if (borderHeight > 0.0 && d->height() < borderHeight) {
|
---|
533 | qreal diff = borderHeight - d->height() - 1;
|
---|
534 | top -= qRound(diff * qreal(top) / borderHeight);
|
---|
535 | bottom -= qRound(diff * qreal(bottom) / borderHeight);
|
---|
536 | }
|
---|
537 | QMargins margins(left, top, right, bottom);
|
---|
538 | QTileRules rules((Qt::TileRule)d->horizontalTileMode, (Qt::TileRule)d->verticalTileMode);
|
---|
539 | qDrawBorderPixmap(p, QRect(0, 0, (int)d->width(), (int)d->height()), margins, d->pix, d->pix.rect(), margins, rules);
|
---|
540 | if (d->smooth) {
|
---|
541 | p->setRenderHint(QPainter::Antialiasing, oldAA);
|
---|
542 | p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
|
---|
543 | }
|
---|
544 | }
|
---|
545 |
|
---|
546 | QT_END_NAMESPACE
|
---|