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 }