Warning, /plasma/plasma-desktop/kcms/keyboard/tastenbrett/qml/ShapeCanvas.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 SPDX-FileCopyrightText: 2019 Harald Sitter <sitter@kde.org>
0003
0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006
0007 import QtQuick 2.12
0008 import QtQuick.Controls 2.5
0009
0010 Canvas {
0011 property QtObject shape
0012 property variant strokeSyle: "yellow"
0013 property variant fillStyle: "steelblue"
0014 // Only draw one outline. Outlines are tricky because xkb has no
0015 // concept of displaying text on top of the shapes. IOW: it
0016 // only thinks about blank keys. This means we have no layout
0017 // constraints for our text and as a result we'd have to figure out
0018 // where to put text so it doesn't conflict with any of the drawn
0019 // paths and is inside most/all of them. It's not worth the work...
0020 property int maxOutline: 1
0021 // use a round number, we divide this by two to balance spacing
0022 property real lineWidth: 4.0
0023 // scoot away from 0,0 to translation,translation
0024 property real translation: lineWidth / 2.0
0025 // reduce the scale to account for the scoot of translation
0026 property real scale: Math.min((width - lineWidth) / width, (height - lineWidth) / height)
0027
0028 id: canvas
0029 width: shape.bounds.width
0030 height: shape.bounds.height
0031 onStrokeSyleChanged: requestPaint()
0032 onFillStyleChanged: requestPaint()
0033
0034 onPaint: {
0035 var ctx = getContext("2d")
0036 ctx.reset()
0037 ctx.lineWidth = lineWidth
0038 ctx.strokeStyle = strokeSyle
0039 ctx.fillStyle = fillStyle
0040 // Transform the context a bunch. The way strokes work is that
0041 // they extend to the left and right of the path, so with a
0042 // lineWidth of 8 we'll need the entire scene scooted so
0043 // 0,0 becomes 4,4. Since that also would screw up our absolute
0044 // coordinates towards the right (e.g. our width bounds as reported
0045 // by XKB) we also need to then adjust the scale so the entire
0046 // coordinate system so the scene leaves sufficient space at all
0047 // borders.
0048 // i.e. we move the scene so the top and right strokes are fully
0049 // visible and then shrink it so the left and bottom are fully visible.
0050 ctx.translate(translation, translation)
0051 ctx.scale(scale, scale)
0052
0053 ctx.beginPath()
0054
0055 for (var i in shape.outlines) {
0056 if (maxOutline && i >= maxOutline) {
0057 break;
0058 }
0059
0060 var outline = shape.outlines[i]
0061
0062 if (outline.points.length === 1) { // rect from 0,0 to point
0063 var point = outline.points[0]
0064
0065 ctx.roundedRect(0, 0,
0066 point.x, point.y,
0067 outline.corner_radius, outline.corner_radius)
0068 } else if (outline.points.length === 2) { // rect from p1 to p2
0069 var topLeftPoint = outline.points[0]
0070 var bottomRightPoint = outline.points[1]
0071
0072 ctx.roundedRect(topLeftPoint.x, topLeftPoint.y,
0073 bottomRightPoint.x, bottomRightPoint.y,
0074 outline.corner_radius, outline.corner_radius)
0075 } else { // polygon point to point draw (used for doodads and non-rect keys such as Enter)
0076 for (var j in outline.points) {
0077 var anyPoint = outline.points[j]
0078 if (j < 1) { // move to first point
0079 ctx.moveTo(anyPoint.x, anyPoint.y)
0080 } else { // from there we draw point to point
0081 ctx.lineTo(anyPoint.x, anyPoint.y)
0082 }
0083
0084 // TODO: should probably draw short of target and then arcTo over the target so we get a round corner?
0085 // Currently shapes are not rounded.
0086 }
0087 }
0088 }
0089
0090 ctx.closePath()
0091 if (fillStyle) {
0092 ctx.fill()
0093 }
0094 ctx.stroke()
0095 }
0096 }