import QtQuick 2.0 import QtGraphicalEffects 1.0 Item { id: c; width: tileSize; height: tileSize; property double tileSize : 100; property double internalTileSize : 100; property var entryA : null; property var exitA : null; property double volume : 0; property color colour : 'green'; property string label : ''; property string _maskSource : ''; property int _maskRotation : 0; property string _maskLetter : ''; function setup() { var source = '', rotation = 0, letter = ''; if (rotate(c.entryA, 180) == c.exitA) { source = 'straight'; rotation = c.entryA; } else if (rotate(c.entryA, 90) == c.exitA) { source = 'corner'; rotation = c.entryA; } else if (rotate(c.exitA, 90) == c.entryA) { source = 'corner'; rotation = c.exitA; } else if (isOrtho(c.entryA) && !isOrtho(c.exitA)) { source = 'end'; rotation = c.entryA; letter = 'E'; } else if (isOrtho(c.exitA) && !isOrtho(c.entryA)) { source = 'end'; rotation = c.exitA; letter = 'S'; } else { source = 'full'; letter = 'X'; } c._maskSource = source; c._maskRotation = rotation; c._maskLetter = letter; } Component.onCompleted: setup(); onEntryAChanged: setup(); onExitAChanged: setup(); function rotate(a, d) { return isOrtho(a) ? (a+d)%360 : -1; } function isOrtho(a) { return a == 0 || a == 90 || a == 180 || a == 270; } DropShadow { anchors.fill: c; radius: 0.025*c.tileSize; spread: 0.8; fast: true; color: 'black'; opacity: 0.2; source: uncached_mask; layer.enabled: true; clip: true; } LinearGradient { function steer(n, dir) { switch (dir) { case 0: return {x: 0.5, y: n}; case 90: return {x: 1-n, y: 0.5}; case 180: return {x: 0.5, y: 1-n}; case 270: return {x: n, y: 0.5}; } return {x: 0.5, y: 0.5}; } function point(p) { return Qt.point(p.x*c.width, p.y*c.height); } function calc(vol, t, ena, exa) { var band = 0.3; var t2 = t + band; if (!isOrtho(ena)) { vol = 0.4+vol*0.6; ena = rotate(exa, 180); } else if (!isOrtho(exa)) { vol = vol*0.6; exa = rotate(ena, 180); } exa = rotate(exa, 180); if (vol < t) { return point(steer(vol, ena)); } else if (vol < t2) { var v = (vol-t)/band; var a = steer(t, ena); var b = steer(t2, exa); return point({x: a.x*(1-v)+b.x*v, y: a.y*(1-v)+b.y*v}); } else { return point(steer(vol, exa)); } } id: grad; anchors.fill: parent; start: calc(c.volume-0.1, 0.3, c.entryA, c.exitA); end: calc(c.volume, 0.4, c.entryA, c.exitA); gradient: Gradient { GradientStop { position: 0.0; color: colour; } GradientStop { position: 1.0; color: Qt.rgba(0,0,0,0.1); } } source: mask; } Item { id: mask; anchors.fill: parent; visible: false; layer.enabled: true; Item { id: uncached_mask; anchors.fill: parent; Image { anchors.fill: parent; rotation: c._maskRotation; source: c._maskSource + '_mask.svg'; sourceSize.width: c.internalTileSize; sourceSize.height: c.internalTileSize; } } } Item { anchors.fill: parent; visible: c._maskLetter != ''; Text { anchors.centerIn: parent; font.pixelSize: 0.2*c.tileSize; text: c._maskLetter; color: c.colour.r + c.colour.g + c.colour.b > 1.5 ? Qt.darker(c.colour, 2) : Qt.lighter(c.colour, 2); } Item { anchors.fill: parent; rotation: rotate(c._maskRotation, 270) % 180; Text { x: rotate(c._maskRotation,90) <= 90 ? 0 : 0.4*c.tileSize; y: 0.25*c.tileSize; width: 0.6*c.tileSize; horizontalAlignment: rotate(c._maskRotation,90) <= 90 ? Text.AlignRight : Text.AlignLeft; font.pixelSize: 0.1*c.tileSize; text: c.label; } } } }