Files

136 lines
4.7 KiB
QML
Raw Permalink Normal View History

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Flora
Rectangle {
id: root
property string code: ""
property string language: "text"
property string codeId: ""
signal copyRequested(string codeId)
// Telegram-like bubble
color: "#2e4d6a"
radius: 12
// adaptive width like Telegram message
width: parent ? Math.min(parent.width * 0.88, implicitWidth) : implicitWidth
implicitWidth: 400
implicitHeight: column.implicitHeight + 20
// For syntax highlighting, we use a TextArea with RichText
// The highlighted code is set from outside via highlightedText
property string highlightedText: ""
Column {
id: column
width: parent.width - 20
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 10
spacing: 6
// Header with language and copy button — строго справа
RowLayout {
width: parent.width
height: 24
spacing: 8
Label {
text: root.language.toUpperCase()
color: "#8a9ba8"
font.pixelSize: 10
font.bold: true
font.letterSpacing: 0.4
Layout.alignment: Qt.AlignVCenter
visible: root.language !== "text" && root.language !== ""
}
Item {
Layout.fillWidth: true
height: 1
}
Label {
id: languageLabel
text: root.language
visible: false
}
// Copy button - Telegram style, hover/active feedback
Rectangle {
id: copyButton
Layout.preferredWidth: copyLabel.implicitWidth + 16
Layout.preferredHeight: 22
implicitWidth: copyLabel.implicitWidth + 16
implicitHeight: 22
radius: 11
color: copyHover.hovered ? (copyTap.pressed ? Qt.rgba(1,1,1,0.30) : Qt.rgba(1,1,1,0.22)) : Qt.rgba(1,1,1,0.12)
border.color: copyHover.hovered ? Qt.rgba(1,1,1,0.28) : Qt.rgba(1,1,1,0.18)
border.width: 1
property bool copied: false
Timer { id: copyResetTimer; interval: 1500; onTriggered: copyButton.copied = false }
Label {
id: copyLabel
anchors.centerIn: parent
text: copyButton.copied ? "✓" : "📋"
color: copyButton.copied ? "#6ab2f6" : "#ffffff"
font.pixelSize: 13
font.family: "-apple-system, sans-serif"
}
HoverHandler { id: copyHover }
TapHandler {
id: copyTap
onTapped: {
root.copyRequested(root.codeId)
copyButton.copied = true
copyResetTimer.restart()
}
}
// For mouse cursor
HoverHandler {
cursorShape: Qt.PointingHandCursor
}
}
}
// Code area - как в редакторе, но без скролла — весь текст виден целиком
Rectangle {
width: parent.width
color: Qt.rgba(0,0,0,0.22)
radius: 8
implicitHeight: codeText.implicitHeight + 20
TextEdit {
id: codeText
anchors.fill: parent
anchors.margins: 10
// Сохраняем форматирование как ввёл пользователь: оборачиваем в <pre> с pre-wrap
text: {
let src = root.highlightedText
if (!src || src.length === 0) {
src = root.code.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;")
}
return "<pre style=\"margin:0;white-space:pre-wrap;word-wrap:break-word;tab-size:4;\">" + src + "</pre>"
}
textFormat: TextEdit.RichText
wrapMode: TextEdit.Wrap
readOnly: true
selectByMouse: true
color: "#ffffff"
selectionColor: "#3a6ea5"
selectedTextColor: "#ffffff"
font.family: "JetBrains Mono, Fira Code, Menlo, Consolas, monospace"
font.pixelSize: 13
}
}
}
// For bracket matching highlight in editor, we could add a similar indicator
// But for preview, this is just display
}