KOSMIndoorMap

scenegraphitem.cpp
1/*
2 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "scenegraphitem.h"
8#include "view.h"
9
10#include <QDebug>
11#include <QFontMetrics>
12
13using namespace KOSMIndoorMap;
14
15SceneGraphItemPayload::~SceneGraphItemPayload() = default;
16
18{
19 return renderPhases() & (FillPhase | StrokePhase | CasingPhase);
20}
21
23{
24 return renderPhases() & (IconPhase | LabelPhase);
25}
26
27
29{
30 return (pen.style() != Qt::NoPen ? StrokePhase : NoPhase) | (casingPen.style() != Qt::NoPen ? CasingPhase : NoPhase);
31}
32
34{
35 auto r = path.boundingRect(); // TODO do we need to cache this?
36 double w = 0.0;
37 switch (penWidthUnit) {
38 case Unit::Pixel:
40 break;
41 case Unit::Meter:
42 w += view->mapMetersToScene(pen.widthF());
43 break;
44 }
45 switch (casingPenWidthUnit) {
46 case Unit::Pixel:
47 w += view->mapScreenDistanceToSceneDistance(casingPen.widthF());
48 break;
49 case Unit::Meter:
50 w += view->mapMetersToScene(casingPen.widthF());
51 break;
52 }
53 w /= 2.0;
54 r.adjust(-w, -w, w, w);
55 return r;
56}
57
58
60{
61 if (useCasingFillMode()) {
62 return StrokePhase | CasingPhase;
63 }
64 return (pen.style() == Qt::NoPen ? NoPhase : StrokePhase)
65 | (fillBrush.style() == Qt::NoBrush && textureBrush.style() == Qt::NoBrush ? NoPhase : FillPhase);
66}
67
69{
70 return casingPen.style() != Qt::NoPen && (fillBrush.style() != Qt::NoBrush || textureBrush.style() != Qt::NoBrush);
71}
72
73QRectF PolygonItem::boundingRect([[maybe_unused]] const View *view) const
74{
75 return polygon.boundingRect(); // TODO do we need to cache this?
76}
77
78QRectF MultiPolygonItem::boundingRect([[maybe_unused]] const View *view) const
79{
80 return path.boundingRect(); // TODO do we need to cache this?
81}
82
83
85{
86 if (hasShield()) {
87 return IconPhase;
88 }
89 return (hasIcon() ? IconPhase : NoPhase) | (hasText() ? LabelPhase : NoPhase);
90}
91
93{
94 QRectF bbox;
95 if (hasText()) {
96 bbox = QRectF(QPointF(0.0, 0.0), textOutputSize());
97 }
98 if (hasIcon()) {
99 const auto s = iconOutputSize(view);
100 bbox.setHeight(bbox.height() + s.height());
101 bbox.setWidth(std::max(bbox.width(), s.width()));
102 }
103
104 const auto shieldSize = casingAndFrameWidth();
105 bbox.adjust(-shieldSize, -shieldSize, shieldSize, shieldSize);
106
107 bbox.moveCenter(pos);
108 return bbox;
109}
110
111QRectF LabelItem::iconHitBox(const View *view) const
112{
113 auto bbox = QRectF(QPointF(0.0, 0.0), iconOutputSize(view));
114 bbox.moveCenter(view->mapSceneToScreen(pos));
115 return bbox;
116}
117
118QRectF LabelItem::textHitBox(const View *view) const
119{
120 auto bbox = QRectF(QPointF(0.0, 0.0), textOutputSize());
121 bbox.moveCenter(view->mapSceneToScreen(pos));
122 if (hasIcon()) {
123 bbox.moveTop(iconHitBox(view).top() + textOffset);
124 } else {
125 bbox.moveTop(bbox.top() + textOffset); // TODO textOffset unit
126 }
127 return bbox;
128}
129
130QRectF LabelItem::shieldHitBox(const View *view) const
131{
132 auto bbox = iconHitBox(view).united(textHitBox(view));
133 const auto w = casingAndFrameWidth();
134 bbox.adjust(-w, -w, w, w);
135 return bbox;
136}
137
138QSizeF LabelItem::iconOutputSize(const View *view) const
139{
140 if (!hasIcon()) {
141 return {};
142 }
143
144 const auto h = iconHeightUnit == Unit::Meter ? view->mapMetersToScreen(iconSize.height()) : iconSize.height();
145 const auto w = iconWidthUnit == Unit::Meter ? view->mapMetersToScreen(iconSize.width()) : iconSize.width();
146 return {w, h};
147}
148
149QSizeF LabelItem::textOutputSize() const
150{
151 if (textOutputSizeCache.isEmpty() && hasText()) {
152 // QStaticText::size doesn't return the actual bounding box with QStaticText::textWidth is set,
153 // so we need to compute this manually here to not end up with overly large hitboxes
154 if (text.textWidth() > 0) {
155 textOutputSizeCache = QFontMetricsF(font).boundingRect({QPointF(0.0, 0.0), QSizeF(text.textWidth(), 1000.0)}, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, text.text()).size();
156 } else {
157 textOutputSizeCache = QFontMetricsF(font).size(0, text.text());
158 }
159 }
160
161 return textOutputSizeCache;
162}
163
164double LabelItem::casingAndFrameWidth() const
165{
166 return std::max(frameWidth, haloRadius) + casingWidth;
167}
168
169bool LabelItem::hasIcon() const
170{
171 return !icon.isNull();
172}
173
174bool LabelItem::hasShield() const
175{
176 return (casingWidth > 0.0 && casingColor.alpha() > 0)
177 || (frameWidth > 0.0 && frameColor.alpha() > 0)
178 || shieldColor.alpha() > 0;
179}
QRectF boundingRect(const View *view) const override
Bounding box of this item in scene coordinates.
uint8_t renderPhases() const override
Returns in which phase this item needs to be rendered (can be multiple).
QRectF boundingRect(const View *view) const override
Bounding box of this item in scene coordinates.
uint8_t renderPhases() const override
Returns in which phase this item needs to be rendered (can be multiple).
bool useCasingFillMode() const
Render like lines, ie casing and filling in the stroke phase, rather than the default.
QRectF boundingRect(const View *view) const override
Bounding box of this item in scene coordinates.
uint8_t renderPhases() const override
Returns in which phase this item needs to be rendered (can be multiple).
QRectF boundingRect(const View *view) const override
Bounding box of this item in scene coordinates.
virtual uint8_t renderPhases() const =0
Returns in which phase this item needs to be rendered (can be multiple).
bool inSceneSpace() const
Is this item drawn in scene coordinates (as oposed to HUD coordinates)?
bool inHUDSpace() const
Is this item drawn in HUD coordinates (as oposed to scene coordinates)?
View transformations and transformation manipulation.
Definition view.h:40
double mapMetersToScene(double meters) const
Returns how many units in scene coordinate represent the distance of meters in the current view trans...
Definition view.cpp:257
double mapScreenDistanceToSceneDistance(double distance) const
Converts a distance in screen coordinates to a distance in scene coordinates.
Definition view.cpp:191
QPointF mapSceneToScreen(QPointF scenePos) const
Converts a point in scene coordinates to screen coordinates.
Definition view.cpp:175
OSM-based multi-floor indoor maps for buildings.
Qt::BrushStyle style() const const
int alpha() const const
QRectF boundingRect(QChar ch) const const
QSizeF size(int flags, const QString &text, int tabStops, int *tabArray) const const
bool isNull() const const
QRectF boundingRect() const const
Qt::PenStyle style() const const
qreal widthF() const const
QRectF boundingRect() const const
void adjust(qreal dx1, qreal dy1, qreal dx2, qreal dy2)
qreal height() const const
void moveCenter(const QPointF &position)
void setHeight(qreal height)
void setWidth(qreal width)
QRectF united(const QRectF &rectangle) const const
qreal width() const const
qreal height() const const
bool isEmpty() const const
qreal width() const const
QString text() const const
qreal textWidth() const const
AlignHCenter
TextWordWrap
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:03 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.