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 }