sidebar: translator: language selector

This commit is contained in:
end-4
2025-06-11 10:59:52 +02:00
parent 244d3f6067
commit 65983ade46
8 changed files with 439 additions and 156 deletions
@@ -0,0 +1,42 @@
import "root:/"
import "root:/services"
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/string_utils.js" as StringUtils
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
RippleButton {
id: root
property string displayText: ""
colBackground: Appearance.colors.colLayer2
contentItem: Item {
anchors.centerIn: parent
implicitWidth: languageRow.implicitWidth
implicitHeight: languageText.implicitHeight
RowLayout {
id: languageRow
anchors.centerIn: parent
spacing: 0
StyledText {
id: languageText
Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: 5
text: root.displayText
color: Appearance.colors.colOnLayer2
font.pixelSize: Appearance.font.pixelSize.small
}
MaterialSymbol {
Layout.alignment: Qt.AlignVCenter
iconSize: Appearance.font.pixelSize.hugeass
text: "arrow_drop_down"
color: Appearance.colors.colOnLayer2
}
}
}
}
@@ -0,0 +1,92 @@
import "root:/"
import "root:/services"
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/string_utils.js" as StringUtils
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
Rectangle {
id: root
property bool isInput: true // true for input, false for output
property string placeholderText
property string text: ""
property var inputTextArea: isInput ? inputLoader.item : undefined
readonly property string displayedText: isInput ? inputLoader.item.text :
root.text.length > 0 ? outputLoader.item.text : ""
default property alias actionButtons: actions.data
Layout.fillWidth: true
implicitHeight: Math.max(150, inputColumn.implicitHeight)
color: isInput ? Appearance.colors.colLayer1 : Appearance.m3colors.m3surfaceContainer
radius: Appearance.rounding.normal
border.color: isInput ? Appearance.m3colors.m3outlineVariant : "transparent"
border.width: isInput ? 1 : 0
signal inputTextChanged(); // Signal emitted when text changes
ColumnLayout {
id: inputColumn
anchors.fill: parent
spacing: 0
Loader {
id: inputLoader
active: root.isInput
visible: root.isInput
Layout.fillWidth: true
sourceComponent: StyledTextArea { // Input area
id: inputTextArea
placeholderText: root.placeholderText
wrapMode: TextEdit.Wrap
textFormat: TextEdit.PlainText
font.pixelSize: Appearance.font.pixelSize.small
color: Appearance.colors.colOnLayer1
padding: 15
background: null
onTextChanged: root.inputTextChanged()
}
}
Loader {
id: outputLoader
active: !root.isInput
visible: !root.isInput
Layout.fillWidth: true
sourceComponent: StyledText { // Output area
id: outputTextArea
padding: 15
wrapMode: Text.Wrap
font.pixelSize: Appearance.font.pixelSize.small
color: root.text.length > 0 ? Appearance.colors.colOnLayer1 : Appearance.colors.colSubtext
text: root.text.length > 0 ? root.text : root.placeholderText
}
}
Item { Layout.fillHeight: true }
RowLayout { // Status row
Layout.fillWidth: true
Layout.margins: 10
spacing: 10
Loader {
active: root.isInput
visible: root.isInput
Layout.leftMargin: 10
sourceComponent: Text {
text: qsTr("%1 characters").arg(inputLoader.item.text.length)
color: Appearance.colors.colOnLayer1
font.pixelSize: Appearance.font.pixelSize.smaller
}
}
Item { Layout.fillWidth: true }
ButtonGroup {
id: actions
}
}
}
}