mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 20:58:38 +02:00
Merge pull request #6963 from jherico/qmlOverlays
Make all 2D overlays QML-based
This commit is contained in:
commit
8efe15cb21
19 changed files with 413 additions and 495 deletions
|
@ -236,18 +236,10 @@
|
||||||
"dimensions"
|
"dimensions"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
ImageOverlay = generateOverlayClass(Overlay2D, "image", [
|
|
||||||
"subImage", "imageURL"
|
|
||||||
]);
|
|
||||||
|
|
||||||
Image3DOverlay = generateOverlayClass(Billboard3DOverlay, "image3d", [
|
Image3DOverlay = generateOverlayClass(Billboard3DOverlay, "image3d", [
|
||||||
"url", "subImage"
|
"url", "subImage"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
TextOverlay = generateOverlayClass(Overlay2D, "text", [
|
|
||||||
"font", "text", "backgroundColor", "backgroundAlpha", "leftMargin", "topMargin"
|
|
||||||
]);
|
|
||||||
|
|
||||||
Text3DOverlay = generateOverlayClass(Billboard3DOverlay, "text3d", [
|
Text3DOverlay = generateOverlayClass(Billboard3DOverlay, "text3d", [
|
||||||
"text", "backgroundColor", "backgroundAlpha", "lineHeight", "leftMargin", "topMargin",
|
"text", "backgroundColor", "backgroundAlpha", "lineHeight", "leftMargin", "topMargin",
|
||||||
"rightMargin", "bottomMargin"
|
"rightMargin", "bottomMargin"
|
||||||
|
|
|
@ -132,14 +132,15 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.width = 0;
|
this.width = 0;
|
||||||
this.height = ToolBar.TITLE_BAR_HEIGHT;
|
this.height = ToolBar.TITLE_BAR_HEIGHT;
|
||||||
this.back = this.back = Overlays.addOverlay("text", {
|
this.backAlpha = 1.0;
|
||||||
backgroundColor: { red: 255, green: 255, blue: 255 },
|
this.back = Overlays.addOverlay("rectangle", {
|
||||||
|
color: { red: 255, green: 255, blue: 255 },
|
||||||
x: this.x,
|
x: this.x,
|
||||||
y: this.y,
|
y: this.y,
|
||||||
|
radius: 4,
|
||||||
width: this.width,
|
width: this.width,
|
||||||
height: this.height,
|
height: this.height,
|
||||||
alpha: 1.0,
|
alpha: this.backAlpha,
|
||||||
backgroundAlpha: 1.0,
|
|
||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
this.spacing = [];
|
this.spacing = [];
|
||||||
|
@ -246,10 +247,8 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
this.tools[tool].setAlpha(alpha);
|
this.tools[tool].setAlpha(alpha);
|
||||||
}
|
}
|
||||||
if (this.back != null) {
|
if (this.back != null) {
|
||||||
Overlays.editOverlay(this.back, {
|
this.backAlpha = alpha;
|
||||||
alpha: alpha,
|
Overlays.editOverlay(this.back, { alpha: alpha });
|
||||||
backgroundAlpha: alpha
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.tools[tool].setAlpha(alpha);
|
this.tools[tool].setAlpha(alpha);
|
||||||
|
@ -258,9 +257,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
|
|
||||||
this.setBack = function(color, alpha) {
|
this.setBack = function(color, alpha) {
|
||||||
if (color == null) {
|
if (color == null) {
|
||||||
Overlays.editOverlay(this.back, {
|
Overlays.editOverlay(this.back, { visible: false });
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
Overlays.editOverlay(this.back, {
|
Overlays.editOverlay(this.back, {
|
||||||
width: this.width +
|
width: this.width +
|
||||||
|
@ -268,8 +265,8 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
height: this.height +
|
height: this.height +
|
||||||
((direction == ToolBar.VERTICAL) ? 1 : 2) * ToolBar.SPACING,
|
((direction == ToolBar.VERTICAL) ? 1 : 2) * ToolBar.SPACING,
|
||||||
visible: true,
|
visible: true,
|
||||||
backgroundColor: color,
|
color: color,
|
||||||
backgroundAlpha: alpha
|
alpha: alpha
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,12 +336,9 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
that.hover = function (enable) { // Can be overriden or extended by clients.
|
that.hover = function (enable) { // Can be overriden or extended by clients.
|
||||||
that.isHovering = enable;
|
that.isHovering = enable;
|
||||||
if (that.back) {
|
if (that.back) {
|
||||||
if (enable) {
|
|
||||||
that.oldAlpha = Overlays.getProperty(that.back, 'backgroundAlpha');
|
|
||||||
}
|
|
||||||
Overlays.editOverlay(this.back, {
|
Overlays.editOverlay(this.back, {
|
||||||
visible: enable,
|
visible: enable,
|
||||||
backgroundAlpha: enable ? 0.5 : that.oldAlpha
|
alpha: enable ? 0.5 : that.backAlpha
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import Hifi 1.0
|
|
||||||
import QtQuick 2.3
|
|
||||||
import QtQuick.Controls 1.2
|
|
||||||
|
|
||||||
TextOverlayElement {
|
|
||||||
id: root
|
|
||||||
Rectangle {
|
|
||||||
color: root.backgroundColor
|
|
||||||
anchors.fill: parent
|
|
||||||
Text {
|
|
||||||
x: root.leftMargin
|
|
||||||
y: root.topMargin
|
|
||||||
id: text
|
|
||||||
objectName: "textElement"
|
|
||||||
text: root.text
|
|
||||||
color: root.textColor
|
|
||||||
font.family: root.fontFamily
|
|
||||||
font.pixelSize: root.fontSize
|
|
||||||
lineHeightMode: Text.FixedHeight
|
|
||||||
lineHeight: root.lineHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,7 +25,7 @@ FocusScope {
|
||||||
readonly property alias zLevels: zLevels
|
readonly property alias zLevels: zLevels
|
||||||
QtObject {
|
QtObject {
|
||||||
id: zLevels;
|
id: zLevels;
|
||||||
readonly property real normal: 0
|
readonly property real normal: 1 // make windows always appear higher than QML overlays and other non-window controls.
|
||||||
readonly property real top: 2000
|
readonly property real top: 2000
|
||||||
readonly property real modal: 4000
|
readonly property real modal: 4000
|
||||||
readonly property real menu: 8000
|
readonly property real menu: 8000
|
||||||
|
|
78
interface/resources/qml/hifi/overlays/ImageOverlay.qml
Normal file
78
interface/resources/qml/hifi/overlays/ImageOverlay.qml
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Overlay {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: image
|
||||||
|
property bool scaleFix: true;
|
||||||
|
property real xOffset: 0
|
||||||
|
property real yOffset: 0
|
||||||
|
property real imageScale: 1.0
|
||||||
|
property var resizer: Timer {
|
||||||
|
interval: 50
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
onTriggered: {
|
||||||
|
var targetAspect = root.width / root.height;
|
||||||
|
var sourceAspect = image.sourceSize.width / image.sourceSize.height;
|
||||||
|
if (sourceAspect <= targetAspect) {
|
||||||
|
if (root.width === image.sourceSize.width) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
image.imageScale = root.width / image.sourceSize.width;
|
||||||
|
} else if (sourceAspect > targetAspect){
|
||||||
|
if (root.height === image.sourceSize.height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
image.imageScale = root.height / image.sourceSize.height;
|
||||||
|
}
|
||||||
|
image.sourceSize = Qt.size(image.sourceSize.width * image.imageScale, image.sourceSize.height * image.imageScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x: -1 * xOffset * imageScale
|
||||||
|
y: -1 * yOffset * imageScale
|
||||||
|
|
||||||
|
onSourceSizeChanged: {
|
||||||
|
if (sourceSize.width !== 0 && sourceSize.height !== 0 && progress === 1.0 && scaleFix) {
|
||||||
|
scaleFix = false;
|
||||||
|
resizer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSubImage(subImage) {
|
||||||
|
var keys = Object.keys(subImage);
|
||||||
|
for (var i = 0; i < keys.length; ++i) {
|
||||||
|
var key = keys[i];
|
||||||
|
var value = subImage[key];
|
||||||
|
switch (key) {
|
||||||
|
case "x": image.xOffset = value; break;
|
||||||
|
case "y": image.yOffset = value; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePropertiesFromScript(properties) {
|
||||||
|
var keys = Object.keys(properties);
|
||||||
|
for (var i = 0; i < keys.length; ++i) {
|
||||||
|
var key = keys[i];
|
||||||
|
var value = properties[key];
|
||||||
|
switch (key) {
|
||||||
|
case "height": root.height = value; break;
|
||||||
|
case "width": root.width = value; break;
|
||||||
|
case "x": root.x = value; break;
|
||||||
|
case "y": root.y = value; break;
|
||||||
|
case "visible": root.visible = value; break;
|
||||||
|
case "alpha": root.opacity = value; break;
|
||||||
|
case "imageURL": image.source = value; break;
|
||||||
|
case "subImage": updateSubImage(value); break;
|
||||||
|
default: console.log("OVERLAY Unhandled image property " + key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
30
interface/resources/qml/hifi/overlays/Overlay.qml
Normal file
30
interface/resources/qml/hifi/overlays/Overlay.qml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import Hifi 1.0
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
property int dumpDepth: 0;
|
||||||
|
|
||||||
|
|
||||||
|
function dumpObject(object) {
|
||||||
|
var keys = Object.keys(object);
|
||||||
|
var tabsString = "";
|
||||||
|
for (var j = 0; j < dumpDepth; ++j) {
|
||||||
|
tabsString = tabsString + "\t";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < keys.length; ++i) {
|
||||||
|
var key = keys[i];
|
||||||
|
var value = object[key];
|
||||||
|
console.log(tabsString + "OVERLAY Key " + key + " (" + typeof(value) + "): " + value);
|
||||||
|
if (typeof(value) === "object") {
|
||||||
|
++dumpDepth;
|
||||||
|
dumpObject(value)
|
||||||
|
--dumpDepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
interface/resources/qml/hifi/overlays/RectangleOverlay.qml
Normal file
38
interface/resources/qml/hifi/overlays/RectangleOverlay.qml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Overlay {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePropertiesFromScript(properties) {
|
||||||
|
var keys = Object.keys(properties);
|
||||||
|
for (var i = 0; i < keys.length; ++i) {
|
||||||
|
var key = keys[i];
|
||||||
|
var value = properties[key];
|
||||||
|
console.log("OVERLAY rectangle property " + key + " set to value " + value);
|
||||||
|
switch (key) {
|
||||||
|
case "height": root.height = value; break;
|
||||||
|
case "width": root.width = value; break;
|
||||||
|
case "x": root.x = value; break;
|
||||||
|
case "y": root.y = value; break;
|
||||||
|
case "visible": root.visible = value; break;
|
||||||
|
case "alpha": rectangle.color.a = value; break;
|
||||||
|
case "color": rectangle.color = Qt.rgba(value.red / 255, value.green / 255, value.blue / 255, rectangle.color.a); break;
|
||||||
|
case "borderAlpha": rectangle.border.color.a = value; break;
|
||||||
|
case "borderColor": rectangle.border.color = Qt.rgba(value.red / 255, value.green / 255, value.blue / 255, rectangle.border.color.a); break;
|
||||||
|
case "borderWidth": rectangle.border.width = value; break;
|
||||||
|
case "radius": rectangle.radius = value; break;
|
||||||
|
default: console.log("OVERLAY Unhandled rectangle property " + key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
54
interface/resources/qml/hifi/overlays/TextOverlay.qml
Normal file
54
interface/resources/qml/hifi/overlays/TextOverlay.qml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Overlay {
|
||||||
|
id: root
|
||||||
|
clip: true
|
||||||
|
Rectangle {
|
||||||
|
id: background;
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#B2000000"
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: textField;
|
||||||
|
anchors { fill: parent; bottomMargin: textField.anchors.topMargin; rightMargin: textField.anchors.leftMargin; }
|
||||||
|
objectName: "textElement"
|
||||||
|
color: "white"
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
font.family: "Helvetica"
|
||||||
|
font.pixelSize: 18
|
||||||
|
lineHeight: 18
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updatePropertiesFromScript(properties) {
|
||||||
|
var keys = Object.keys(properties);
|
||||||
|
for (var i = 0; i < keys.length; ++i) {
|
||||||
|
var key = keys[i];
|
||||||
|
var value = properties[key];
|
||||||
|
switch (key) {
|
||||||
|
case "height": root.height = value; break;
|
||||||
|
case "width": root.width = value; break;
|
||||||
|
case "x": root.x = value; break;
|
||||||
|
case "y": root.y = value; break;
|
||||||
|
case "visible": root.visible = value; break;
|
||||||
|
case "alpha": textField.color.a = value; break;
|
||||||
|
case "margin": textField.anchors.margins = value; break;
|
||||||
|
case "leftMargin": textField.anchors.leftMargin = value; break;
|
||||||
|
case "topMargin": textField.anchors.topMargin = value; break;
|
||||||
|
case "color": // fall through
|
||||||
|
case "textColor": textField.color = Qt.rgba(value.red / 255, value.green / 255, value.blue / 255, textField.color.a); break;
|
||||||
|
case "text": textField.text = value; break;
|
||||||
|
case "backgroundAlpha": background.color = Qt.rgba(background.color.r, background.color.g, background.color.b, value); break;
|
||||||
|
case "backgroundColor": background.color = Qt.rgba(value.red / 255, value.green / 255, value.blue / 255, background.color.a); break;
|
||||||
|
case "font": textField.font.pixelSize = value.size; break;
|
||||||
|
case "lineHeight": textField.lineHeight = value; break;
|
||||||
|
default:
|
||||||
|
console.log("OVERLAY text unhandled property " + key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,159 +17,15 @@
|
||||||
|
|
||||||
|
|
||||||
QString const ImageOverlay::TYPE = "image";
|
QString const ImageOverlay::TYPE = "image";
|
||||||
|
QUrl const ImageOverlay::URL(QString("hifi/overlays/ImageOverlay.qml"));
|
||||||
|
|
||||||
ImageOverlay::ImageOverlay() :
|
ImageOverlay::ImageOverlay()
|
||||||
_imageURL(),
|
: QmlOverlay(URL) { }
|
||||||
_renderImage(false),
|
|
||||||
_wantClipFromImage(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) :
|
ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) :
|
||||||
Overlay2D(imageOverlay),
|
QmlOverlay(URL, imageOverlay) { }
|
||||||
_imageURL(imageOverlay->_imageURL),
|
|
||||||
_textureImage(imageOverlay->_textureImage),
|
|
||||||
_texture(imageOverlay->_texture),
|
|
||||||
_fromImage(imageOverlay->_fromImage),
|
|
||||||
_renderImage(imageOverlay->_renderImage),
|
|
||||||
_wantClipFromImage(imageOverlay->_wantClipFromImage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: handle setting image multiple times, how do we manage releasing the bound texture?
|
|
||||||
void ImageOverlay::setImageURL(const QUrl& url) {
|
|
||||||
_imageURL = url;
|
|
||||||
if (url.isEmpty()) {
|
|
||||||
_isLoaded = true;
|
|
||||||
_renderImage = false;
|
|
||||||
_texture.clear();
|
|
||||||
} else {
|
|
||||||
_isLoaded = false;
|
|
||||||
_renderImage = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageOverlay::render(RenderArgs* args) {
|
|
||||||
if (!_isLoaded && _renderImage) {
|
|
||||||
_isLoaded = true;
|
|
||||||
_texture = DependencyManager::get<TextureCache>()->getTexture(_imageURL);
|
|
||||||
}
|
|
||||||
// If we are not visible or loaded, return. If we are trying to render an
|
|
||||||
// image but the texture hasn't loaded, return.
|
|
||||||
if (!_visible || !_isLoaded || (_renderImage && !_texture->isLoaded())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
|
||||||
gpu::Batch& batch = *args->_batch;
|
|
||||||
geometryCache->useSimpleDrawPipeline(batch);
|
|
||||||
if (_renderImage) {
|
|
||||||
batch.setResourceTexture(0, _texture->getGPUTexture());
|
|
||||||
} else {
|
|
||||||
batch.setResourceTexture(0, args->_whiteTexture);
|
|
||||||
}
|
|
||||||
|
|
||||||
const float MAX_COLOR = 255.0f;
|
|
||||||
xColor color = getColor();
|
|
||||||
float alpha = getAlpha();
|
|
||||||
glm::vec4 quadColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
|
||||||
|
|
||||||
int left = _bounds.left();
|
|
||||||
int right = _bounds.right() + 1;
|
|
||||||
int top = _bounds.top();
|
|
||||||
int bottom = _bounds.bottom() + 1;
|
|
||||||
|
|
||||||
glm::vec2 topLeft(left, top);
|
|
||||||
glm::vec2 bottomRight(right, bottom);
|
|
||||||
|
|
||||||
batch.setModelTransform(Transform());
|
|
||||||
|
|
||||||
// if for some reason our image is not over 0 width or height, don't attempt to render the image
|
|
||||||
if (_renderImage) {
|
|
||||||
float imageWidth = _texture->getWidth();
|
|
||||||
float imageHeight = _texture->getHeight();
|
|
||||||
if (imageWidth > 0 && imageHeight > 0) {
|
|
||||||
QRect fromImage;
|
|
||||||
if (_wantClipFromImage) {
|
|
||||||
float scaleX = imageWidth / _texture->getOriginalWidth();
|
|
||||||
float scaleY = imageHeight / _texture->getOriginalHeight();
|
|
||||||
|
|
||||||
fromImage.setX(scaleX * _fromImage.x());
|
|
||||||
fromImage.setY(scaleY * _fromImage.y());
|
|
||||||
fromImage.setWidth(scaleX * _fromImage.width());
|
|
||||||
fromImage.setHeight(scaleY * _fromImage.height());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fromImage.setX(0);
|
|
||||||
fromImage.setY(0);
|
|
||||||
fromImage.setWidth(imageWidth);
|
|
||||||
fromImage.setHeight(imageHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
float x = fromImage.x() / imageWidth;
|
|
||||||
float y = fromImage.y() / imageHeight;
|
|
||||||
float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure
|
|
||||||
float h = fromImage.height() / imageHeight;
|
|
||||||
|
|
||||||
glm::vec2 texCoordTopLeft(x, y);
|
|
||||||
glm::vec2 texCoordBottomRight(x + w, y + h);
|
|
||||||
glm::vec4 texcoordRect(texCoordTopLeft, w, h);
|
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor);
|
|
||||||
} else {
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageOverlay::setProperties(const QScriptValue& properties) {
|
|
||||||
Overlay2D::setProperties(properties);
|
|
||||||
|
|
||||||
QScriptValue subImageBounds = properties.property("subImage");
|
|
||||||
if (subImageBounds.isValid()) {
|
|
||||||
QRect oldSubImageRect = _fromImage;
|
|
||||||
QRect subImageRect = _fromImage;
|
|
||||||
if (subImageBounds.property("x").isValid()) {
|
|
||||||
subImageRect.setX(subImageBounds.property("x").toVariant().toInt());
|
|
||||||
} else {
|
|
||||||
subImageRect.setX(oldSubImageRect.x());
|
|
||||||
}
|
|
||||||
if (subImageBounds.property("y").isValid()) {
|
|
||||||
subImageRect.setY(subImageBounds.property("y").toVariant().toInt());
|
|
||||||
} else {
|
|
||||||
subImageRect.setY(oldSubImageRect.y());
|
|
||||||
}
|
|
||||||
if (subImageBounds.property("width").isValid()) {
|
|
||||||
subImageRect.setWidth(subImageBounds.property("width").toVariant().toInt());
|
|
||||||
} else {
|
|
||||||
subImageRect.setWidth(oldSubImageRect.width());
|
|
||||||
}
|
|
||||||
if (subImageBounds.property("height").isValid()) {
|
|
||||||
subImageRect.setHeight(subImageBounds.property("height").toVariant().toInt());
|
|
||||||
} else {
|
|
||||||
subImageRect.setHeight(oldSubImageRect.height());
|
|
||||||
}
|
|
||||||
setClipFromSource(subImageRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue imageURL = properties.property("imageURL");
|
|
||||||
if (imageURL.isValid()) {
|
|
||||||
setImageURL(imageURL.toVariant().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue ImageOverlay::getProperty(const QString& property) {
|
|
||||||
if (property == "subImage") {
|
|
||||||
return qRectToScriptValue(_scriptEngine, _fromImage);
|
|
||||||
}
|
|
||||||
if (property == "imageURL") {
|
|
||||||
return _imageURL.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Overlay2D::getProperty(property);
|
|
||||||
}
|
|
||||||
ImageOverlay* ImageOverlay::createClone() const {
|
ImageOverlay* ImageOverlay::createClone() const {
|
||||||
return new ImageOverlay(this);
|
return new ImageOverlay(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,48 +11,22 @@
|
||||||
#ifndef hifi_ImageOverlay_h
|
#ifndef hifi_ImageOverlay_h
|
||||||
#define hifi_ImageOverlay_h
|
#define hifi_ImageOverlay_h
|
||||||
|
|
||||||
// include this before QGLWidget, which includes an earlier version of OpenGL
|
|
||||||
#include <QImage>
|
|
||||||
#include <QRect>
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <TextureCache.h>
|
#include "QmlOverlay.h"
|
||||||
|
|
||||||
#include "Overlay2D.h"
|
class ImageOverlay : public QmlOverlay {
|
||||||
|
|
||||||
class ImageOverlay : public Overlay2D {
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const { return TYPE; }
|
||||||
|
static QUrl const URL;
|
||||||
|
|
||||||
ImageOverlay();
|
ImageOverlay();
|
||||||
ImageOverlay(const ImageOverlay* imageOverlay);
|
ImageOverlay(const ImageOverlay* imageOverlay);
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual ImageOverlay* createClone() const override;
|
||||||
|
|
||||||
// getters
|
|
||||||
const QRect& getClipFromSource() const { return _fromImage; }
|
|
||||||
const QUrl& getImageURL() const { return _imageURL; }
|
|
||||||
|
|
||||||
// setters
|
|
||||||
void setClipFromSource(const QRect& bounds) { _fromImage = bounds; _wantClipFromImage = true; }
|
|
||||||
void setImageURL(const QUrl& url);
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
|
||||||
virtual QScriptValue getProperty(const QString& property);
|
|
||||||
|
|
||||||
virtual ImageOverlay* createClone() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
QUrl _imageURL;
|
|
||||||
QImage _textureImage;
|
|
||||||
|
|
||||||
NetworkTexturePointer _texture;
|
|
||||||
QRect _fromImage; // where from in the image to sample
|
|
||||||
bool _renderImage; // is there an image associated with this overlay, or is it just a colored rectangle
|
|
||||||
bool _wantClipFromImage;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
virtual void render(RenderArgs* args) = 0;
|
virtual void render(RenderArgs* args) = 0;
|
||||||
|
|
||||||
virtual AABox getBounds() const = 0;
|
virtual AABox getBounds() const = 0;
|
||||||
|
virtual bool supportsGetProperty() const { return true; }
|
||||||
|
|
||||||
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||||
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "Sphere3DOverlay.h"
|
#include "Sphere3DOverlay.h"
|
||||||
#include "Grid3DOverlay.h"
|
#include "Grid3DOverlay.h"
|
||||||
#include "TextOverlay.h"
|
#include "TextOverlay.h"
|
||||||
|
#include "RectangleOverlay.h"
|
||||||
#include "Text3DOverlay.h"
|
#include "Text3DOverlay.h"
|
||||||
#include "Web3DOverlay.h"
|
#include "Web3DOverlay.h"
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
@ -175,6 +176,8 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
|
||||||
thisOverlay = std::make_shared<ModelOverlay>();
|
thisOverlay = std::make_shared<ModelOverlay>();
|
||||||
} else if (type == Web3DOverlay::TYPE) {
|
} else if (type == Web3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Web3DOverlay>();
|
thisOverlay = std::make_shared<Web3DOverlay>();
|
||||||
|
} else if (type == RectangleOverlay::TYPE) {
|
||||||
|
thisOverlay = std::make_shared<RectangleOverlay>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thisOverlay) {
|
if (thisOverlay) {
|
||||||
|
@ -373,7 +376,7 @@ OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& prop
|
||||||
OverlayPropertyResult result;
|
OverlayPropertyResult result;
|
||||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||||
QReadLocker lock(&_lock);
|
QReadLocker lock(&_lock);
|
||||||
if (thisOverlay) {
|
if (thisOverlay && thisOverlay->supportsGetProperty()) {
|
||||||
result.value = thisOverlay->getProperty(property);
|
result.value = thisOverlay->getProperty(property);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
74
interface/src/ui/overlays/QmlOverlay.cpp
Normal file
74
interface/src/ui/overlays/QmlOverlay.cpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/01/27
|
||||||
|
// Copyright 2013-2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "QmlOverlay.h"
|
||||||
|
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include <GeometryCache.h>
|
||||||
|
#include <GLMHelpers.h>
|
||||||
|
#include <OffscreenUi.h>
|
||||||
|
#include <RegisteredMetaTypes.h>
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
#include <TextureCache.h>
|
||||||
|
#include <ViewFrustum.h>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
#include "text/FontFamilies.h"
|
||||||
|
|
||||||
|
QmlOverlay::QmlOverlay(const QUrl& url) {
|
||||||
|
buildQmlElement(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlOverlay::QmlOverlay(const QUrl& url, const QmlOverlay* textOverlay)
|
||||||
|
: Overlay2D(textOverlay) {
|
||||||
|
buildQmlElement(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlOverlay::buildQmlElement(const QUrl& url) {
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
offscreenUi->returnFromUiThread([=] {
|
||||||
|
offscreenUi->load(url, [=](QQmlContext* context, QObject* object) {
|
||||||
|
_qmlElement = dynamic_cast<QQuickItem*>(object);
|
||||||
|
});
|
||||||
|
while (!_qmlElement) {
|
||||||
|
qApp->processEvents();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlOverlay::~QmlOverlay() {
|
||||||
|
if (_qmlElement) {
|
||||||
|
_qmlElement->deleteLater();
|
||||||
|
_qmlElement = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlOverlay::setProperties(const QScriptValue& properties) {
|
||||||
|
Overlay2D::setProperties(properties);
|
||||||
|
auto bounds = _bounds;
|
||||||
|
DependencyManager::get<OffscreenUi>()->executeOnUiThread([=] {
|
||||||
|
_qmlElement->setX(bounds.left());
|
||||||
|
_qmlElement->setY(bounds.top());
|
||||||
|
_qmlElement->setWidth(bounds.width());
|
||||||
|
_qmlElement->setHeight(bounds.height());
|
||||||
|
});
|
||||||
|
QMetaObject::invokeMethod(_qmlElement, "updatePropertiesFromScript", Q_ARG(QVariant, properties.toVariant()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlOverlay::render(RenderArgs* args) {
|
||||||
|
if (!_qmlElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_visible != _qmlElement->isVisible()) {
|
||||||
|
_qmlElement->setVisible(_visible);
|
||||||
|
}
|
||||||
|
}
|
41
interface/src/ui/overlays/QmlOverlay.h
Normal file
41
interface/src/ui/overlays/QmlOverlay.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/01/27
|
||||||
|
// Copyright 2013-2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_QmlOverlay_h
|
||||||
|
#define hifi_QmlOverlay_h
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
#include "Overlay2D.h"
|
||||||
|
|
||||||
|
class QQuickItem;
|
||||||
|
|
||||||
|
class QmlOverlay : public Overlay2D {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QmlOverlay(const QUrl& url);
|
||||||
|
QmlOverlay(const QUrl& url, const QmlOverlay* textOverlay);
|
||||||
|
~QmlOverlay();
|
||||||
|
|
||||||
|
// Cannot fetch properties from QML based overlays due to race conditions
|
||||||
|
bool supportsGetProperty() const override { return false; }
|
||||||
|
|
||||||
|
void setProperties(const QScriptValue& properties) override;
|
||||||
|
void render(RenderArgs* args) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void buildQmlElement(const QUrl& url);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QQuickItem* _qmlElement{ nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // hifi_QmlOverlay_h
|
21
interface/src/ui/overlays/RectangleOverlay.cpp
Normal file
21
interface/src/ui/overlays/RectangleOverlay.cpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/01/27
|
||||||
|
// Copyright 2013-2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "RectangleOverlay.h"
|
||||||
|
|
||||||
|
QString const RectangleOverlay::TYPE = "rectangle";
|
||||||
|
QUrl const RectangleOverlay::URL(QString("hifi/overlays/RectangleOverlay.qml"));
|
||||||
|
|
||||||
|
RectangleOverlay::RectangleOverlay() : QmlOverlay(URL) {}
|
||||||
|
|
||||||
|
RectangleOverlay::RectangleOverlay(const RectangleOverlay* rectangleOverlay)
|
||||||
|
: QmlOverlay(URL, rectangleOverlay) { }
|
||||||
|
|
||||||
|
RectangleOverlay* RectangleOverlay::createClone() const {
|
||||||
|
return new RectangleOverlay(this);
|
||||||
|
}
|
27
interface/src/ui/overlays/RectangleOverlay.h
Normal file
27
interface/src/ui/overlays/RectangleOverlay.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/01/27
|
||||||
|
// Copyright 2013-2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_RectangleOverlay_h
|
||||||
|
#define hifi_RectangleOverlay_h
|
||||||
|
|
||||||
|
#include "QmlOverlay.h"
|
||||||
|
|
||||||
|
class RectangleOverlay : public QmlOverlay {
|
||||||
|
public:
|
||||||
|
static QString const TYPE;
|
||||||
|
virtual QString getType() const { return TYPE; }
|
||||||
|
static QUrl const URL;
|
||||||
|
|
||||||
|
RectangleOverlay();
|
||||||
|
RectangleOverlay(const RectangleOverlay* RectangleOverlay);
|
||||||
|
|
||||||
|
virtual RectangleOverlay* createClone() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // hifi_RectangleOverlay_h
|
|
@ -24,216 +24,21 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "text/FontFamilies.h"
|
#include "text/FontFamilies.h"
|
||||||
|
|
||||||
#define TEXT_OVERLAY_PROPERTY(type, name, initialValue) \
|
|
||||||
Q_PROPERTY(type name READ name WRITE set##name NOTIFY name##Changed) \
|
|
||||||
public: \
|
|
||||||
type name() { return _##name; }; \
|
|
||||||
void set##name(const type& name) { \
|
|
||||||
if (name != _##name) { \
|
|
||||||
_##name = name; \
|
|
||||||
emit name##Changed(); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
private: \
|
|
||||||
type _##name{ initialValue };
|
|
||||||
|
|
||||||
|
|
||||||
class TextOverlayElement : public QQuickItem {
|
|
||||||
Q_OBJECT
|
|
||||||
HIFI_QML_DECL
|
|
||||||
private:
|
|
||||||
TEXT_OVERLAY_PROPERTY(QString, text, "")
|
|
||||||
TEXT_OVERLAY_PROPERTY(QString, fontFamily, SANS_FONT_FAMILY)
|
|
||||||
TEXT_OVERLAY_PROPERTY(QString, textColor, "#ffffffff")
|
|
||||||
TEXT_OVERLAY_PROPERTY(QString, backgroundColor, "#B2000000")
|
|
||||||
TEXT_OVERLAY_PROPERTY(qreal, fontSize, 18)
|
|
||||||
TEXT_OVERLAY_PROPERTY(qreal, lineHeight, 18)
|
|
||||||
TEXT_OVERLAY_PROPERTY(qreal, leftMargin, 0)
|
|
||||||
TEXT_OVERLAY_PROPERTY(qreal, topMargin, 0)
|
|
||||||
|
|
||||||
public:
|
|
||||||
TextOverlayElement(QQuickItem* parent = nullptr) : QQuickItem(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void textChanged();
|
|
||||||
void fontFamilyChanged();
|
|
||||||
void fontSizeChanged();
|
|
||||||
void lineHeightChanged();
|
|
||||||
void leftMarginChanged();
|
|
||||||
void topMarginChanged();
|
|
||||||
void textColorChanged();
|
|
||||||
void backgroundColorChanged();
|
|
||||||
};
|
|
||||||
|
|
||||||
HIFI_QML_DEF(TextOverlayElement)
|
|
||||||
|
|
||||||
QString toQmlColor(const glm::vec4& v) {
|
|
||||||
QString templat("#%1%2%3%4");
|
|
||||||
return templat.
|
|
||||||
arg((int)(v.a * 255), 2, 16, QChar('0')).
|
|
||||||
arg((int)(v.r * 255), 2, 16, QChar('0')).
|
|
||||||
arg((int)(v.g * 255), 2, 16, QChar('0')).
|
|
||||||
arg((int)(v.b * 255), 2, 16, QChar('0'));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString const TextOverlay::TYPE = "text";
|
QString const TextOverlay::TYPE = "text";
|
||||||
|
QUrl const TextOverlay::URL(QString("hifi/overlays/TextOverlay.qml"));
|
||||||
|
|
||||||
TextOverlay::TextOverlay() :
|
TextOverlay::TextOverlay() : QmlOverlay(URL) { }
|
||||||
_backgroundColor(DEFAULT_BACKGROUND_COLOR),
|
|
||||||
_backgroundAlpha(DEFAULT_BACKGROUND_ALPHA),
|
TextOverlay::TextOverlay(const TextOverlay* textOverlay)
|
||||||
_leftMargin(DEFAULT_MARGIN),
|
: QmlOverlay(URL, textOverlay) {
|
||||||
_topMargin(DEFAULT_MARGIN),
|
|
||||||
_fontSize(DEFAULT_FONTSIZE)
|
|
||||||
{
|
|
||||||
qApp->postLambdaEvent([=] {
|
|
||||||
static std::once_flag once;
|
|
||||||
std::call_once(once, [] {
|
|
||||||
TextOverlayElement::registerType();
|
|
||||||
});
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
|
||||||
TextOverlayElement::show([=](QQmlContext* context, QObject* object) {
|
|
||||||
_qmlElement = static_cast<TextOverlayElement*>(object);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
while (!_qmlElement) {
|
|
||||||
QThread::msleep(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextOverlay::TextOverlay(const TextOverlay* textOverlay) :
|
TextOverlay::~TextOverlay() { }
|
||||||
Overlay2D(textOverlay),
|
|
||||||
_text(textOverlay->_text),
|
|
||||||
_backgroundColor(textOverlay->_backgroundColor),
|
|
||||||
_backgroundAlpha(textOverlay->_backgroundAlpha),
|
|
||||||
_leftMargin(textOverlay->_leftMargin),
|
|
||||||
_topMargin(textOverlay->_topMargin),
|
|
||||||
_fontSize(textOverlay->_fontSize)
|
|
||||||
{
|
|
||||||
qApp->postLambdaEvent([=] {
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
|
||||||
TextOverlayElement::show([this](QQmlContext* context, QObject* object) {
|
|
||||||
_qmlElement = static_cast<TextOverlayElement*>(object);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
while (!_qmlElement) {
|
|
||||||
QThread::msleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextOverlay::~TextOverlay() {
|
|
||||||
if (_qmlElement) {
|
|
||||||
_qmlElement->deleteLater();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xColor TextOverlay::getBackgroundColor() {
|
|
||||||
if (_colorPulse == 0.0f) {
|
|
||||||
return _backgroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
float pulseLevel = updatePulse();
|
|
||||||
xColor result = _backgroundColor;
|
|
||||||
if (_colorPulse < 0.0f) {
|
|
||||||
result.red *= (1.0f - pulseLevel);
|
|
||||||
result.green *= (1.0f - pulseLevel);
|
|
||||||
result.blue *= (1.0f - pulseLevel);
|
|
||||||
} else {
|
|
||||||
result.red *= pulseLevel;
|
|
||||||
result.green *= pulseLevel;
|
|
||||||
result.blue *= pulseLevel;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextOverlay::render(RenderArgs* args) {
|
|
||||||
if (!_qmlElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_visible != _qmlElement->isVisible()) {
|
|
||||||
_qmlElement->setVisible(_visible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TextOverlay::setProperties(const QScriptValue& properties) {
|
|
||||||
Overlay2D::setProperties(properties);
|
|
||||||
_qmlElement->setX(_bounds.left());
|
|
||||||
_qmlElement->setY(_bounds.top());
|
|
||||||
_qmlElement->setWidth(_bounds.width());
|
|
||||||
_qmlElement->setHeight(_bounds.height());
|
|
||||||
_qmlElement->settextColor(toQmlColor(vec4(toGlm(_color), _alpha)));
|
|
||||||
QScriptValue font = properties.property("font");
|
|
||||||
if (font.isObject()) {
|
|
||||||
if (font.property("size").isValid()) {
|
|
||||||
setFontSize(font.property("size").toInt32());
|
|
||||||
}
|
|
||||||
QFont font(_qmlElement->fontFamily());
|
|
||||||
font.setPixelSize(_qmlElement->fontSize());
|
|
||||||
QFontMetrics fm(font);
|
|
||||||
_qmlElement->setlineHeight(fm.lineSpacing() * 1.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue text = properties.property("text");
|
|
||||||
if (text.isValid()) {
|
|
||||||
setText(text.toVariant().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue backgroundColor = properties.property("backgroundColor");
|
|
||||||
if (backgroundColor.isValid()) {
|
|
||||||
QScriptValue red = backgroundColor.property("red");
|
|
||||||
QScriptValue green = backgroundColor.property("green");
|
|
||||||
QScriptValue blue = backgroundColor.property("blue");
|
|
||||||
if (red.isValid() && green.isValid() && blue.isValid()) {
|
|
||||||
_backgroundColor.red = red.toVariant().toInt();
|
|
||||||
_backgroundColor.green = green.toVariant().toInt();
|
|
||||||
_backgroundColor.blue = blue.toVariant().toInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (properties.property("backgroundAlpha").isValid()) {
|
|
||||||
_backgroundAlpha = properties.property("backgroundAlpha").toVariant().toFloat();
|
|
||||||
}
|
|
||||||
_qmlElement->setbackgroundColor(toQmlColor(vec4(toGlm(_backgroundColor), _backgroundAlpha)));
|
|
||||||
|
|
||||||
if (properties.property("leftMargin").isValid()) {
|
|
||||||
setLeftMargin(properties.property("leftMargin").toVariant().toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (properties.property("topMargin").isValid()) {
|
|
||||||
setTopMargin(properties.property("topMargin").toVariant().toInt());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextOverlay* TextOverlay::createClone() const {
|
TextOverlay* TextOverlay::createClone() const {
|
||||||
return new TextOverlay(this);
|
return new TextOverlay(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue TextOverlay::getProperty(const QString& property) {
|
|
||||||
if (property == "font") {
|
|
||||||
QScriptValue font = _scriptEngine->newObject();
|
|
||||||
font.setProperty("size", _fontSize);
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
if (property == "text") {
|
|
||||||
return _text;
|
|
||||||
}
|
|
||||||
if (property == "backgroundColor") {
|
|
||||||
return xColorToScriptValue(_scriptEngine, _backgroundColor);
|
|
||||||
}
|
|
||||||
if (property == "backgroundAlpha") {
|
|
||||||
return _backgroundAlpha;
|
|
||||||
}
|
|
||||||
if (property == "leftMargin") {
|
|
||||||
return _leftMargin;
|
|
||||||
}
|
|
||||||
if (property == "topMargin") {
|
|
||||||
return _topMargin;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Overlay2D::getProperty(property);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSizeF TextOverlay::textSize(const QString& text) const {
|
QSizeF TextOverlay::textSize(const QString& text) const {
|
||||||
int lines = 1;
|
int lines = 1;
|
||||||
foreach(QChar c, text) {
|
foreach(QChar c, text) {
|
||||||
|
@ -241,31 +46,15 @@ QSizeF TextOverlay::textSize(const QString& text) const {
|
||||||
++lines;
|
++lines;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QFont font(_qmlElement->fontFamily());
|
QFont font(SANS_FONT_FAMILY);
|
||||||
font.setPixelSize(_qmlElement->fontSize());
|
font.setPixelSize(18);
|
||||||
QFontMetrics fm(font);
|
QFontMetrics fm(font);
|
||||||
QSizeF result = QSizeF(fm.width(text), _qmlElement->lineHeight() * lines);
|
QSizeF result = QSizeF(fm.width(text), 18 * lines);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextOverlay::setFontSize(int fontSize) {
|
|
||||||
_fontSize = fontSize;
|
|
||||||
_qmlElement->setfontSize(fontSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextOverlay::setText(const QString& text) {
|
void TextOverlay::setTopMargin(float margin) {}
|
||||||
_text = text;
|
void TextOverlay::setLeftMargin(float margin) {}
|
||||||
_qmlElement->settext(text);
|
void TextOverlay::setFontSize(float size) {}
|
||||||
}
|
void TextOverlay::setText(const QString& text) {}
|
||||||
|
|
||||||
void TextOverlay::setLeftMargin(int margin) {
|
|
||||||
_leftMargin = margin;
|
|
||||||
_qmlElement->setleftMargin(margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextOverlay::setTopMargin(int margin) {
|
|
||||||
_topMargin = margin;
|
|
||||||
_qmlElement->settopMargin(margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "TextOverlay.moc"
|
|
||||||
|
|
|
@ -11,59 +11,27 @@
|
||||||
#ifndef hifi_TextOverlay_h
|
#ifndef hifi_TextOverlay_h
|
||||||
#define hifi_TextOverlay_h
|
#define hifi_TextOverlay_h
|
||||||
|
|
||||||
#include <QString>
|
#include "QmlOverlay.h"
|
||||||
|
|
||||||
#include <SharedUtil.h>
|
class TextOverlay : public QmlOverlay {
|
||||||
|
|
||||||
#include "Overlay2D.h"
|
|
||||||
|
|
||||||
const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 };
|
|
||||||
const float DEFAULT_BACKGROUND_ALPHA = 0.7f;
|
|
||||||
const int DEFAULT_MARGIN = 10;
|
|
||||||
const int DEFAULT_FONTSIZE = 12;
|
|
||||||
const int DEFAULT_FONT_WEIGHT = 50;
|
|
||||||
|
|
||||||
class TextOverlayElement;
|
|
||||||
|
|
||||||
class TextOverlay : public Overlay2D {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
QString getType() const override { return TYPE; }
|
||||||
|
static QUrl const URL;
|
||||||
|
|
||||||
|
|
||||||
TextOverlay();
|
TextOverlay();
|
||||||
TextOverlay(const TextOverlay* textOverlay);
|
TextOverlay(const TextOverlay* textOverlay);
|
||||||
~TextOverlay();
|
~TextOverlay();
|
||||||
virtual void render(RenderArgs* args);
|
|
||||||
|
|
||||||
// getters
|
void setTopMargin(float margin);
|
||||||
const QString& getText() const { return _text; }
|
void setLeftMargin(float margin);
|
||||||
int getLeftMargin() const { return _leftMargin; }
|
void setFontSize(float size);
|
||||||
int getTopMargin() const { return _topMargin; }
|
|
||||||
xColor getBackgroundColor();
|
|
||||||
float getBackgroundAlpha() const { return _backgroundAlpha; }
|
|
||||||
|
|
||||||
// setters
|
|
||||||
void setText(const QString& text);
|
void setText(const QString& text);
|
||||||
void setLeftMargin(int margin);
|
|
||||||
void setTopMargin(int margin);
|
|
||||||
void setFontSize(int fontSize);
|
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
|
||||||
virtual TextOverlay* createClone() const;
|
|
||||||
virtual QScriptValue getProperty(const QString& property);
|
|
||||||
|
|
||||||
|
TextOverlay* createClone() const;
|
||||||
QSizeF textSize(const QString& text) const; // Pixels
|
QSizeF textSize(const QString& text) const; // Pixels
|
||||||
|
|
||||||
private:
|
|
||||||
TextOverlayElement* _qmlElement{ nullptr };
|
|
||||||
QString _text;
|
|
||||||
xColor _backgroundColor;
|
|
||||||
float _backgroundAlpha;
|
|
||||||
int _leftMargin;
|
|
||||||
int _topMargin;
|
|
||||||
int _fontSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,6 @@ DISTFILES += \
|
||||||
../../interface/resources/qml/windows/*.qml \
|
../../interface/resources/qml/windows/*.qml \
|
||||||
../../interface/resources/qml/hifi/*.qml \
|
../../interface/resources/qml/hifi/*.qml \
|
||||||
../../interface/resources/qml/hifi/dialogs/*.qml \
|
../../interface/resources/qml/hifi/dialogs/*.qml \
|
||||||
../../interface/resources/qml/hifi/dialogs/preferences/*.qml
|
../../interface/resources/qml/hifi/dialogs/preferences/*.qml \
|
||||||
|
../../interface/resources/qml/hifi/overlays/*.qml
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue