Give Input keycaps, a shortcut search, and the missing pointer basics
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
// Somewhere to try a pointer change before deciding to keep it.
|
||||
//
|
||||
// Pointer speed, acceleration, scroll direction and scroll speed are all
|
||||
// settings you cannot read: the number means nothing, and the only honest test
|
||||
// is moving the pointer. Every one of them applies live, so this is simply a
|
||||
// place to move it that is not somebody's document.
|
||||
//
|
||||
// Entirely local. Nothing here writes a preference or touches the compositor,
|
||||
// and the scribble is not saved anywhere -- it exists for the length of a
|
||||
// question ("is that too fast?") and is thrown away.
|
||||
//
|
||||
// The canvas repaints only when the pointer has actually moved across it,
|
||||
// driven from the motion handler rather than a timer. A settings page that
|
||||
// repainted continuously would be a persistent GPU load on a high-refresh
|
||||
// display, in return for a picture that had not changed.
|
||||
|
||||
import QtQuick
|
||||
import qs.config
|
||||
|
||||
Column {
|
||||
id: root
|
||||
|
||||
width: parent ? parent.width : 620
|
||||
spacing: 10
|
||||
|
||||
Rectangle {
|
||||
id: pad
|
||||
|
||||
width: parent.width
|
||||
height: 150
|
||||
radius: Theme.cardRadius
|
||||
color: Theme.alpha(Theme.bgDark, 0.55)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.fg, 0.08)
|
||||
clip: true
|
||||
|
||||
// Segments drawn since the last paint. The canvas keeps what it has
|
||||
// already been given, so each paint adds the new piece of the stroke
|
||||
// instead of redrawing the whole scribble.
|
||||
property var pending: []
|
||||
property bool wiping: false
|
||||
property bool drawn: false
|
||||
|
||||
Canvas {
|
||||
id: scribble
|
||||
|
||||
anchors.fill: parent
|
||||
renderStrategy: Canvas.Immediate
|
||||
|
||||
onPaint: {
|
||||
const context = scribble.getContext("2d");
|
||||
if (pad.wiping) {
|
||||
context.reset();
|
||||
pad.wiping = false;
|
||||
pad.pending = [];
|
||||
return;
|
||||
}
|
||||
context.strokeStyle = Theme.accent;
|
||||
context.lineWidth = 2.4;
|
||||
context.lineCap = "round";
|
||||
context.lineJoin = "round";
|
||||
context.beginPath();
|
||||
for (const segment of pad.pending) {
|
||||
context.moveTo(segment.fromX, segment.fromY);
|
||||
context.lineTo(segment.toX, segment.toY);
|
||||
}
|
||||
context.stroke();
|
||||
pad.pending = [];
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: !pad.drawn
|
||||
text: "Draw here to feel pointer speed"
|
||||
color: Theme.fgMuted
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: pointer
|
||||
|
||||
property real lastX: 0
|
||||
property real lastY: 0
|
||||
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.CrossCursor
|
||||
// The page is a Flickable, which would otherwise take the drag off
|
||||
// this and scroll instead of drawing.
|
||||
preventStealing: true
|
||||
|
||||
onPressed: mouse => {
|
||||
pointer.lastX = mouse.x;
|
||||
pointer.lastY = mouse.y;
|
||||
pad.drawn = true;
|
||||
}
|
||||
|
||||
onPositionChanged: mouse => {
|
||||
const segments = pad.pending;
|
||||
segments.push({
|
||||
fromX: pointer.lastX,
|
||||
fromY: pointer.lastY,
|
||||
toX: mouse.x,
|
||||
toY: mouse.y
|
||||
});
|
||||
pad.pending = segments;
|
||||
pointer.lastX = mouse.x;
|
||||
pointer.lastY = mouse.y;
|
||||
scribble.requestPaint();
|
||||
}
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 8
|
||||
visible: pad.drawn
|
||||
text: "Clear"
|
||||
onClicked: {
|
||||
pad.wiping = true;
|
||||
pad.drawn = false;
|
||||
scribble.requestPaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 110
|
||||
radius: Theme.cardRadius
|
||||
color: Theme.alpha(Theme.bgDark, 0.55)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.fg, 0.08)
|
||||
clip: true
|
||||
|
||||
Flickable {
|
||||
id: strip
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
contentWidth: width
|
||||
contentHeight: lines.implicitHeight
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
|
||||
Column {
|
||||
id: lines
|
||||
|
||||
width: parent.width
|
||||
spacing: 6
|
||||
|
||||
Repeater {
|
||||
model: [
|
||||
"Scroll here to feel scroll speed and direction.",
|
||||
"Natural scrolling moves the content with your fingers.",
|
||||
"The quick brown fox jumps over the lazy dog.",
|
||||
"Line four.",
|
||||
"Line five.",
|
||||
"Line six.",
|
||||
"Line seven — still scrolling.",
|
||||
"Line eight.",
|
||||
"Line nine.",
|
||||
"Line ten, the bottom."
|
||||
]
|
||||
|
||||
Text {
|
||||
required property var modelData
|
||||
|
||||
width: lines.width
|
||||
text: String(modelData)
|
||||
color: Theme.fgDim
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user