Files
dots-hyprland/dots/.config/quickshell/ii/modules/common/widgets/SqueezedAnnotationStyledText.qml
T
2026-04-03 19:31:24 +02:00

75 lines
2.3 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import qs.modules.common
// Annotation similar to how Google Lens does it.
Item {
id: root
property real scaleFactor: 1.0
property alias font: textWidget.font
property alias color: textWidget.color
property string text: ""
property bool rotate90: false
property real maxFontPixelSize: 100
visible: false
Component.onCompleted: updateText()
onTextChanged: updateText()
property bool searching: false
property real searchPixelSize: Appearance.font.pixelSize.small
property real renderPixelSize: Appearance.font.pixelSize.small
font.pixelSize: searching ? searchPixelSize : (renderPixelSize * scaleFactor)
function updateText() {
// Do we rotate?
root.rotate90 = false;
const textAspectRatio = textMetrics.width / textMetrics.height
const areaAspectRatio = root.width / root.height
if ((textAspectRatio > 1 && areaAspectRatio < 1) || (textAspectRatio < 1 && areaAspectRatio > 1)) {
root.rotate90 = true;
}
const targetWidth = (root.rotate90 ? root.height : root.width) / root.scaleFactor;
const targetHeight = (root.rotate90 ? root.width : root.height) / root.scaleFactor;
// Binary search to find the correct font size
var lower = 0
var upper = maxFontPixelSize
root.searching = true;
while (upper - lower > 0.00001) {
var mid = (lower + upper) / 2;
// print("bin searching", mid, "target", targetWidth, targetHeight, "actual", textWidget.contentWidth, textWidget.contentHeight);
root.searchPixelSize = mid
if (textWidget.contentHeight > targetHeight) {
upper = mid
} else {
lower = mid
}
}
root.renderPixelSize = lower
root.searching = false;
root.visible = true
}
TextMetrics {
id: textMetrics
text: root.text
font: root.font
}
StyledText {
id: textWidget
anchors.centerIn: parent
width: root.rotate90 ? parent.height : parent.width
text: root.text
rotation: root.rotate90 ? 90 : 0
renderType: Text.QtRendering
wrapMode: Text.Wrap
}
}