mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-28 07:22:50 -05:00
refactor: common DankTextField widget
This commit is contained in:
@@ -18,10 +18,12 @@ PanelWindow {
|
|||||||
// App management
|
// App management
|
||||||
property var categories: AppSearchService.getAllCategories()
|
property var categories: AppSearchService.getAllCategories()
|
||||||
property string selectedCategory: "All"
|
property string selectedCategory: "All"
|
||||||
property var recentApps: Prefs.recentlyUsedApps.map(recentApp => {
|
property var recentApps: Prefs.recentlyUsedApps.map((recentApp) => {
|
||||||
var app = AppSearchService.getAppByExec(recentApp.exec);
|
var app = AppSearchService.getAppByExec(recentApp.exec);
|
||||||
return app && !app.noDisplay ? app : null;
|
return app && !app.noDisplay ? app : null;
|
||||||
}).filter(app => app !== null)
|
}).filter((app) => {
|
||||||
|
return app !== null;
|
||||||
|
})
|
||||||
property var pinnedApps: ["firefox", "code", "terminal", "file-manager"]
|
property var pinnedApps: ["firefox", "code", "terminal", "file-manager"]
|
||||||
property bool showCategories: false
|
property bool showCategories: false
|
||||||
property string viewMode: Prefs.appLauncherViewMode // "list" or "grid"
|
property string viewMode: Prefs.appLauncherViewMode // "list" or "grid"
|
||||||
@@ -140,6 +142,7 @@ PanelWindow {
|
|||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
launcher.isVisible = true;
|
launcher.isVisible = true;
|
||||||
|
searchField.enabled = true;
|
||||||
searchDebounceTimer.stop(); // Stop any pending search
|
searchDebounceTimer.stop(); // Stop any pending search
|
||||||
updateFilteredModel();
|
updateFilteredModel();
|
||||||
Qt.callLater(function() {
|
Qt.callLater(function() {
|
||||||
@@ -148,6 +151,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
|
searchField.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
launcher.isVisible = false;
|
launcher.isVisible = false;
|
||||||
searchDebounceTimer.stop(); // Stop any pending search
|
searchDebounceTimer.stop(); // Stop any pending search
|
||||||
searchField.text = "";
|
searchField.text = "";
|
||||||
@@ -221,8 +225,6 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: iconComponent
|
id: iconComponent
|
||||||
|
|
||||||
@@ -424,117 +426,43 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced search field
|
// Enhanced search field
|
||||||
Rectangle {
|
DankTextField {
|
||||||
id: searchContainer
|
id: searchField
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 52
|
height: 52
|
||||||
radius: Theme.cornerRadiusLarge
|
cornerRadius: Theme.cornerRadiusLarge
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.7)
|
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.7)
|
||||||
border.width: searchField.activeFocus ? 2 : 1
|
normalBorderColor: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
|
||||||
border.color: searchField.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
|
focusedBorderColor: Theme.primary
|
||||||
|
leftIconName: "search"
|
||||||
Row {
|
leftIconSize: Theme.iconSize
|
||||||
anchors.fill: parent
|
leftIconColor: Theme.surfaceVariantText
|
||||||
anchors.leftMargin: Theme.spacingL
|
leftIconFocusedColor: Theme.primary
|
||||||
anchors.rightMargin: Theme.spacingL
|
showClearButton: true
|
||||||
spacing: Theme.spacingM
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
focus: launcher.isVisible
|
||||||
DankIcon {
|
enabled: launcher.isVisible
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
placeholderText: "Search applications..."
|
||||||
name: "search"
|
onTextEdited: {
|
||||||
size: Theme.iconSize
|
searchDebounceTimer.restart();
|
||||||
color: searchField.activeFocus ? Theme.primary : Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
TextInput {
|
|
||||||
id: searchField
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
width: parent.width - parent.spacing - Theme.iconSize - 32
|
|
||||||
height: parent.height - Theme.spacingS
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
focus: launcher.isVisible
|
|
||||||
selectByMouse: true
|
|
||||||
activeFocusOnTab: true
|
|
||||||
onTextChanged: {
|
|
||||||
searchDebounceTimer.restart();
|
|
||||||
}
|
|
||||||
Keys.onPressed: function(event) {
|
|
||||||
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && filteredModel.count) {
|
|
||||||
var firstApp = filteredModel.get(0);
|
|
||||||
if (firstApp.desktopEntry) {
|
|
||||||
Prefs.addRecentApp(firstApp.desktopEntry);
|
|
||||||
firstApp.desktopEntry.execute();
|
|
||||||
} else {
|
|
||||||
launcher.launchApp(firstApp.exec);
|
|
||||||
}
|
|
||||||
launcher.hide();
|
|
||||||
event.accepted = true;
|
|
||||||
} else if (event.key === Qt.Key_Escape) {
|
|
||||||
launcher.hide();
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
}
|
|
||||||
|
|
||||||
// Placeholder text
|
|
||||||
Text {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: "Search applications..."
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
visible: searchField.text.length === 0 && !searchField.activeFocus
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear button
|
|
||||||
Rectangle {
|
|
||||||
width: 24
|
|
||||||
height: 24
|
|
||||||
radius: 12
|
|
||||||
color: clearSearchArea.containsMouse ? Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) : "transparent"
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: searchField.text.length > 0
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "close"
|
|
||||||
size: 16
|
|
||||||
color: clearSearchArea.containsMouse ? Theme.outline : Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: clearSearchArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: searchField.text = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Keys.onPressed: function(event) {
|
||||||
Behavior on border.color {
|
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && filteredModel.count) {
|
||||||
ColorAnimation {
|
var firstApp = filteredModel.get(0);
|
||||||
duration: Theme.shortDuration
|
if (firstApp.desktopEntry) {
|
||||||
easing.type: Theme.standardEasing
|
Prefs.addRecentApp(firstApp.desktopEntry);
|
||||||
|
firstApp.desktopEntry.execute();
|
||||||
|
} else {
|
||||||
|
launcher.launchApp(firstApp.exec);
|
||||||
|
}
|
||||||
|
launcher.hide();
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_Escape) {
|
||||||
|
launcher.hide();
|
||||||
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Category filter and view mode controls
|
// Category filter and view mode controls
|
||||||
@@ -656,6 +584,7 @@ PanelWindow {
|
|||||||
// List view
|
// List view
|
||||||
DankListView {
|
DankListView {
|
||||||
id: appList
|
id: appList
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: viewMode === "list"
|
visible: viewMode === "list"
|
||||||
model: filteredModel
|
model: filteredModel
|
||||||
@@ -680,6 +609,7 @@ PanelWindow {
|
|||||||
// Grid view
|
// Grid view
|
||||||
DankGridView {
|
DankGridView {
|
||||||
id: appGrid
|
id: appGrid
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: viewMode === "grid"
|
visible: viewMode === "grid"
|
||||||
model: filteredModel
|
model: filteredModel
|
||||||
@@ -821,6 +751,4 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,14 +49,17 @@ PanelWindow {
|
|||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
clipboardHistory.isVisible = true;
|
clipboardHistory.isVisible = true;
|
||||||
searchField.focus = true;
|
searchField.enabled = true;
|
||||||
refreshClipboard();
|
refreshClipboard();
|
||||||
|
Qt.callLater(function() {
|
||||||
|
searchField.forceActiveFocus();
|
||||||
|
});
|
||||||
console.log("ClipboardHistory: Opening and refreshing");
|
console.log("ClipboardHistory: Opening and refreshing");
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
|
searchField.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
clipboardHistory.isVisible = false;
|
clipboardHistory.isVisible = false;
|
||||||
searchField.focus = false;
|
|
||||||
searchField.text = "";
|
searchField.text = "";
|
||||||
// Clean up temporary image files
|
// Clean up temporary image files
|
||||||
cleanupTempFiles();
|
cleanupTempFiles();
|
||||||
@@ -244,71 +247,30 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search field
|
// Search field
|
||||||
Rectangle {
|
DankTextField {
|
||||||
|
id: searchField
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 48
|
height: 48
|
||||||
radius: activeTheme.cornerRadiusLarge
|
cornerRadius: activeTheme.cornerRadiusLarge
|
||||||
color: Qt.rgba(activeTheme.surfaceVariant.r, activeTheme.surfaceVariant.g, activeTheme.surfaceVariant.b, activeTheme.getContentBackgroundAlpha() * 0.4)
|
backgroundColor: Qt.rgba(activeTheme.surfaceVariant.r, activeTheme.surfaceVariant.g, activeTheme.surfaceVariant.b, activeTheme.getContentBackgroundAlpha() * 0.4)
|
||||||
border.color: searchField.focus ? activeTheme.primary : Qt.rgba(activeTheme.outline.r, activeTheme.outline.g, activeTheme.outline.b, 0.08)
|
normalBorderColor: Qt.rgba(activeTheme.outline.r, activeTheme.outline.g, activeTheme.outline.b, 0.08)
|
||||||
border.width: searchField.focus ? 2 : 1
|
focusedBorderColor: activeTheme.primary
|
||||||
|
leftIconName: "search"
|
||||||
Row {
|
leftIconSize: activeTheme.iconSize
|
||||||
anchors.left: parent.left
|
leftIconColor: Qt.rgba(activeTheme.surfaceText.r, activeTheme.surfaceText.g, activeTheme.surfaceText.b, 0.6)
|
||||||
anchors.leftMargin: activeTheme.spacingL
|
leftIconFocusedColor: activeTheme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
showClearButton: true
|
||||||
spacing: activeTheme.spacingM
|
font.pixelSize: activeTheme.fontSizeLarge
|
||||||
|
textColor: activeTheme.surfaceText
|
||||||
DankIcon {
|
placeholderText: "Search clipboard entries..."
|
||||||
name: "search"
|
enabled: clipboardHistory.isVisible
|
||||||
size: activeTheme.iconSize
|
onTextEdited: updateFilteredModel()
|
||||||
color: searchField.focus ? activeTheme.primary : Qt.rgba(activeTheme.surfaceText.r, activeTheme.surfaceText.g, activeTheme.surfaceText.b, 0.6)
|
Keys.onPressed: (event) => {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
if (event.key === Qt.Key_Escape)
|
||||||
}
|
clipboardHistory.hide();
|
||||||
|
|
||||||
TextInput {
|
|
||||||
id: searchField
|
|
||||||
|
|
||||||
width: parent.parent.width - 80
|
|
||||||
height: parent.parent.height
|
|
||||||
font.pixelSize: activeTheme.fontSizeLarge
|
|
||||||
color: activeTheme.surfaceText
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
selectByMouse: true
|
|
||||||
enabled: clipboardHistory.isVisible
|
|
||||||
onTextChanged: updateFilteredModel()
|
|
||||||
Keys.onPressed: (event) => {
|
|
||||||
if (event.key === Qt.Key_Escape)
|
|
||||||
clipboardHistory.hide();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
}
|
|
||||||
|
|
||||||
// Placeholder text
|
|
||||||
Text {
|
|
||||||
text: "Search clipboard entries..."
|
|
||||||
font: searchField.font
|
|
||||||
color: Qt.rgba(activeTheme.surfaceText.r, activeTheme.surfaceText.g, activeTheme.surfaceText.b, 0.6)
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: searchField.text.length === 0 && !searchField.focus
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on border.color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: activeTheme.shortDuration
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hideDialog() {
|
function hideDialog() {
|
||||||
|
textInput.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
dialogVisible = false;
|
dialogVisible = false;
|
||||||
inputValue = "";
|
inputValue = "";
|
||||||
}
|
}
|
||||||
@@ -44,8 +45,13 @@ PanelWindow {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
textInput.forceActiveFocus();
|
textInput.enabled = true;
|
||||||
textInput.text = inputValue;
|
Qt.callLater(function() {
|
||||||
|
textInput.forceActiveFocus();
|
||||||
|
textInput.text = inputValue;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
textInput.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +70,7 @@ PanelWindow {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
textInput.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
inputDialog.cancelled();
|
inputDialog.cancelled();
|
||||||
hideDialog();
|
hideDialog();
|
||||||
}
|
}
|
||||||
@@ -144,18 +151,19 @@ PanelWindow {
|
|||||||
border.color: textInput.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: textInput.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: textInput.activeFocus ? 2 : 1
|
border.width: textInput.activeFocus ? 2 : 1
|
||||||
|
|
||||||
TextInput {
|
DankTextField {
|
||||||
id: textInput
|
id: textInput
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Theme.surfaceText
|
textColor: Theme.surfaceText
|
||||||
echoMode: isPassword && !showPasswordCheckbox.checked ? TextInput.Password : TextInput.Normal
|
echoMode: isPassword && !showPasswordCheckbox.checked ? TextInput.Password : TextInput.Normal
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
enabled: dialogVisible
|
||||||
cursorVisible: activeFocus
|
placeholderText: inputPlaceholder
|
||||||
selectByMouse: true
|
backgroundColor: "transparent"
|
||||||
onTextChanged: {
|
normalBorderColor: "transparent"
|
||||||
|
focusedBorderColor: "transparent"
|
||||||
|
onTextEdited: {
|
||||||
inputValue = text;
|
inputValue = text;
|
||||||
}
|
}
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
@@ -168,23 +176,6 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.fill: parent
|
|
||||||
text: inputPlaceholder
|
|
||||||
font: parent.font
|
|
||||||
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
visible: parent.text.length === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
onClicked: {
|
|
||||||
textInput.forceActiveFocus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -269,6 +260,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
textInput.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
inputDialog.cancelled();
|
inputDialog.cancelled();
|
||||||
hideDialog();
|
hideDialog();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -385,36 +385,21 @@ PanelWindow {
|
|||||||
border.color: profileImageInput.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
|
border.color: profileImageInput.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
|
||||||
border.width: profileImageInput.activeFocus ? 2 : 1
|
border.width: profileImageInput.activeFocus ? 2 : 1
|
||||||
|
|
||||||
TextInput {
|
DankTextField {
|
||||||
id: profileImageInput
|
id: profileImageInput
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
textColor: Theme.surfaceText
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
text: Prefs.profileImage
|
text: Prefs.profileImage
|
||||||
selectByMouse: true
|
placeholderText: "Enter image path or URL..."
|
||||||
|
backgroundColor: "transparent"
|
||||||
|
normalBorderColor: "transparent"
|
||||||
|
focusedBorderColor: "transparent"
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
Prefs.setProfileImage(text);
|
Prefs.setProfileImage(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Placeholder text
|
|
||||||
Text {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: "Enter image path or URL..."
|
|
||||||
color: Qt.rgba(Theme.surfaceVariantText.r, Theme.surfaceVariantText.g, Theme.surfaceVariantText.b, 0.6)
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
visible: profileImageInput.text.length === 0 && !profileImageInput.activeFocus
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -498,36 +483,21 @@ PanelWindow {
|
|||||||
border.color: weatherLocationInput.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
|
border.color: weatherLocationInput.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
|
||||||
border.width: weatherLocationInput.activeFocus ? 2 : 1
|
border.width: weatherLocationInput.activeFocus ? 2 : 1
|
||||||
|
|
||||||
TextInput {
|
DankTextField {
|
||||||
id: weatherLocationInput
|
id: weatherLocationInput
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
textColor: Theme.surfaceText
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
text: Prefs.weatherLocationOverride
|
text: Prefs.weatherLocationOverride
|
||||||
selectByMouse: true
|
placeholderText: "Enter location..."
|
||||||
|
backgroundColor: "transparent"
|
||||||
|
normalBorderColor: "transparent"
|
||||||
|
focusedBorderColor: "transparent"
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
Prefs.setWeatherLocationOverride(text);
|
Prefs.setWeatherLocationOverride(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Placeholder text
|
|
||||||
Text {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: "Enter location..."
|
|
||||||
color: Qt.rgba(Theme.surfaceVariantText.r, Theme.surfaceVariantText.g, Theme.surfaceVariantText.b, 0.6)
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
visible: weatherLocationInput.text.length === 0 && !weatherLocationInput.activeFocus
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ PanelWindow {
|
|||||||
function show() {
|
function show() {
|
||||||
console.log("SpotlightLauncher: show() called");
|
console.log("SpotlightLauncher: show() called");
|
||||||
spotlightOpen = true;
|
spotlightOpen = true;
|
||||||
|
searchField.enabled = true;
|
||||||
console.log("SpotlightLauncher: spotlightOpen set to", spotlightOpen);
|
console.log("SpotlightLauncher: spotlightOpen set to", spotlightOpen);
|
||||||
searchDebounceTimer.stop(); // Stop any pending search
|
searchDebounceTimer.stop(); // Stop any pending search
|
||||||
updateFilteredApps(); // Immediate update when showing
|
updateFilteredApps(); // Immediate update when showing
|
||||||
@@ -43,6 +44,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
|
searchField.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
spotlightOpen = false;
|
spotlightOpen = false;
|
||||||
searchDebounceTimer.stop(); // Stop any pending search
|
searchDebounceTimer.stop(); // Stop any pending search
|
||||||
searchField.text = "";
|
searchField.text = "";
|
||||||
@@ -239,7 +241,6 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: AppSearchService
|
|
||||||
function onReadyChanged() {
|
function onReadyChanged() {
|
||||||
if (AppSearchService.ready) {
|
if (AppSearchService.ready) {
|
||||||
var allCategories = AppSearchService.getAllCategories().filter((cat) => {
|
var allCategories = AppSearchService.getAllCategories().filter((cat) => {
|
||||||
@@ -255,8 +256,9 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
target: AppSearchService
|
||||||
|
}
|
||||||
|
|
||||||
// Dimmed overlay background
|
// Dimmed overlay background
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -426,92 +428,49 @@ PanelWindow {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Rectangle {
|
DankTextField {
|
||||||
id: searchContainer
|
id: searchField
|
||||||
|
|
||||||
width: parent.width - 80 - Theme.spacingM // Leave space for view toggle buttons
|
width: parent.width - 80 - Theme.spacingM // Leave space for view toggle buttons
|
||||||
height: 56
|
height: 56
|
||||||
radius: Theme.cornerRadiusLarge
|
cornerRadius: Theme.cornerRadiusLarge
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.7)
|
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.7)
|
||||||
border.width: searchField.activeFocus ? 2 : 1
|
normalBorderColor: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.color: searchField.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
focusedBorderColor: Theme.primary
|
||||||
|
leftIconName: "search"
|
||||||
Row {
|
leftIconSize: Theme.iconSize
|
||||||
anchors.fill: parent
|
leftIconColor: Theme.surfaceVariantText
|
||||||
anchors.leftMargin: Theme.spacingL
|
leftIconFocusedColor: Theme.primary
|
||||||
anchors.rightMargin: Theme.spacingL
|
showClearButton: true
|
||||||
spacing: Theme.spacingM
|
textColor: Theme.surfaceText
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
DankIcon {
|
focus: spotlightOpen
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
enabled: spotlightOpen
|
||||||
name: "search"
|
placeholderText: "Search applications..."
|
||||||
size: Theme.iconSize
|
onTextEdited: {
|
||||||
color: searchField.activeFocus ? Theme.primary : Theme.surfaceVariantText
|
searchDebounceTimer.restart();
|
||||||
}
|
|
||||||
|
|
||||||
TextInput {
|
|
||||||
id: searchField
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
width: parent.width - parent.spacing - Theme.iconSize - 32
|
|
||||||
height: parent.height - Theme.spacingS
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
focus: spotlightOpen
|
|
||||||
selectByMouse: true
|
|
||||||
onTextChanged: {
|
|
||||||
searchDebounceTimer.restart();
|
|
||||||
}
|
|
||||||
Keys.onPressed: (event) => {
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
|
||||||
hide();
|
|
||||||
event.accepted = true;
|
|
||||||
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
|
||||||
launchSelected();
|
|
||||||
event.accepted = true;
|
|
||||||
} else if (event.key === Qt.Key_Down) {
|
|
||||||
selectNext();
|
|
||||||
event.accepted = true;
|
|
||||||
} else if (event.key === Qt.Key_Up) {
|
|
||||||
selectPrevious();
|
|
||||||
event.accepted = true;
|
|
||||||
} else if (event.key === Qt.Key_Right && viewMode === "grid") {
|
|
||||||
selectNextInRow();
|
|
||||||
event.accepted = true;
|
|
||||||
} else if (event.key === Qt.Key_Left && viewMode === "grid") {
|
|
||||||
selectPreviousInRow();
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: "Search applications..."
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
visible: searchField.text.length === 0 && !searchField.activeFocus
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Keys.onPressed: (event) => {
|
||||||
Behavior on border.color {
|
if (event.key === Qt.Key_Escape) {
|
||||||
ColorAnimation {
|
hide();
|
||||||
duration: Theme.shortDuration
|
event.accepted = true;
|
||||||
easing.type: Theme.standardEasing
|
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||||
|
launchSelected();
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_Down) {
|
||||||
|
selectNext();
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_Up) {
|
||||||
|
selectPrevious();
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_Right && viewMode === "grid") {
|
||||||
|
selectNextInRow();
|
||||||
|
event.accepted = true;
|
||||||
|
} else if (event.key === Qt.Key_Left && viewMode === "grid") {
|
||||||
|
selectPreviousInRow();
|
||||||
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// View mode toggle buttons next to search bar
|
// View mode toggle buttons next to search bar
|
||||||
@@ -595,6 +554,7 @@ PanelWindow {
|
|||||||
// List view
|
// List view
|
||||||
DankListView {
|
DankListView {
|
||||||
id: resultsList
|
id: resultsList
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: viewMode === "list"
|
visible: viewMode === "list"
|
||||||
model: filteredModel
|
model: filteredModel
|
||||||
@@ -613,6 +573,7 @@ PanelWindow {
|
|||||||
// Grid view
|
// Grid view
|
||||||
DankGridView {
|
DankGridView {
|
||||||
id: resultsGrid
|
id: resultsGrid
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: viewMode === "grid"
|
visible: viewMode === "grid"
|
||||||
model: filteredModel
|
model: filteredModel
|
||||||
|
|||||||
@@ -20,9 +20,14 @@ PanelWindow {
|
|||||||
WlrLayershell.keyboardFocus: wifiPasswordDialogVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: wifiPasswordDialogVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible)
|
if (visible) {
|
||||||
passwordInput.forceActiveFocus();
|
passwordInput.enabled = true;
|
||||||
|
Qt.callLater(function() {
|
||||||
|
passwordInput.forceActiveFocus();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
passwordInput.enabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
@@ -40,6 +45,7 @@ PanelWindow {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
passwordInput.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
wifiPasswordDialogVisible = false;
|
wifiPasswordDialogVisible = false;
|
||||||
wifiPasswordInput = "";
|
wifiPasswordInput = "";
|
||||||
}
|
}
|
||||||
@@ -102,6 +108,7 @@ PanelWindow {
|
|||||||
iconColor: Theme.surfaceText
|
iconColor: Theme.surfaceText
|
||||||
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
passwordInput.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
wifiPasswordDialogVisible = false;
|
wifiPasswordDialogVisible = false;
|
||||||
wifiPasswordInput = "";
|
wifiPasswordInput = "";
|
||||||
}
|
}
|
||||||
@@ -118,18 +125,19 @@ PanelWindow {
|
|||||||
border.color: passwordInput.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: passwordInput.activeFocus ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: passwordInput.activeFocus ? 2 : 1
|
border.width: passwordInput.activeFocus ? 2 : 1
|
||||||
|
|
||||||
TextInput {
|
DankTextField {
|
||||||
id: passwordInput
|
id: passwordInput
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Theme.surfaceText
|
textColor: Theme.surfaceText
|
||||||
echoMode: showPasswordCheckbox.checked ? TextInput.Normal : TextInput.Password
|
echoMode: showPasswordCheckbox.checked ? TextInput.Normal : TextInput.Password
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
enabled: wifiPasswordDialogVisible
|
||||||
cursorVisible: activeFocus
|
placeholderText: "Enter password"
|
||||||
selectByMouse: true
|
backgroundColor: "transparent"
|
||||||
onTextChanged: {
|
normalBorderColor: "transparent"
|
||||||
|
focusedBorderColor: "transparent"
|
||||||
|
onTextEdited: {
|
||||||
wifiPasswordInput = text;
|
wifiPasswordInput = text;
|
||||||
}
|
}
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
@@ -141,23 +149,6 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.fill: parent
|
|
||||||
text: "Enter password"
|
|
||||||
font: parent.font
|
|
||||||
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
visible: parent.text.length === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
onClicked: {
|
|
||||||
passwordInput.forceActiveFocus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -241,6 +232,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
passwordInput.enabled = false; // Disable before hiding to prevent Wayland warnings
|
||||||
wifiPasswordDialogVisible = false;
|
wifiPasswordDialogVisible = false;
|
||||||
wifiPasswordInput = "";
|
wifiPasswordInput = "";
|
||||||
}
|
}
|
||||||
|
|||||||
196
Widgets/DankTextField.qml
Normal file
196
Widgets/DankTextField.qml
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias text: textInput.text
|
||||||
|
property string placeholderText: ""
|
||||||
|
property alias font: textInput.font
|
||||||
|
property alias textColor: textInput.color
|
||||||
|
property alias selectByMouse: textInput.selectByMouse
|
||||||
|
property alias enabled: textInput.enabled
|
||||||
|
property alias echoMode: textInput.echoMode
|
||||||
|
property alias verticalAlignment: textInput.verticalAlignment
|
||||||
|
property alias cursorVisible: textInput.cursorVisible
|
||||||
|
property alias readOnly: textInput.readOnly
|
||||||
|
property alias validator: textInput.validator
|
||||||
|
property alias inputMethodHints: textInput.inputMethodHints
|
||||||
|
property alias maximumLength: textInput.maximumLength
|
||||||
|
// Icon properties
|
||||||
|
property string leftIconName: ""
|
||||||
|
property int leftIconSize: Theme.iconSize
|
||||||
|
property color leftIconColor: Theme.surfaceVariantText
|
||||||
|
property color leftIconFocusedColor: Theme.primary
|
||||||
|
property bool showClearButton: false
|
||||||
|
// Custom properties
|
||||||
|
property color backgroundColor: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9)
|
||||||
|
property color focusedBorderColor: Theme.primary
|
||||||
|
property color normalBorderColor: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
|
property color placeholderColor: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
|
||||||
|
property int borderWidth: 1
|
||||||
|
property int focusedBorderWidth: 2
|
||||||
|
property real cornerRadius: Theme.cornerRadius
|
||||||
|
// Internal padding calculations
|
||||||
|
readonly property real leftPadding: Theme.spacingM + (leftIconName ? leftIconSize + Theme.spacingM : 0)
|
||||||
|
readonly property real rightPadding: Theme.spacingM + (showClearButton && text.length > 0 ? 24 + Theme.spacingM : 0)
|
||||||
|
property real topPadding: Theme.spacingM
|
||||||
|
property real bottomPadding: Theme.spacingM
|
||||||
|
|
||||||
|
// Signals
|
||||||
|
signal textEdited()
|
||||||
|
signal editingFinished()
|
||||||
|
signal accepted()
|
||||||
|
signal focusChanged(bool hasFocus)
|
||||||
|
|
||||||
|
// Access to inner TextInput properties via functions
|
||||||
|
function getActiveFocus() {
|
||||||
|
return textInput.activeFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFocus() {
|
||||||
|
return textInput.focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFocus(value) {
|
||||||
|
textInput.focus = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
function forceActiveFocus() {
|
||||||
|
textInput.forceActiveFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAll() {
|
||||||
|
textInput.selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
textInput.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
function paste() {
|
||||||
|
textInput.paste();
|
||||||
|
}
|
||||||
|
|
||||||
|
function copy() {
|
||||||
|
textInput.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cut() {
|
||||||
|
textInput.cut();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default styling
|
||||||
|
width: 200
|
||||||
|
height: 48
|
||||||
|
radius: cornerRadius
|
||||||
|
color: backgroundColor
|
||||||
|
border.color: textInput.activeFocus ? focusedBorderColor : normalBorderColor
|
||||||
|
border.width: textInput.activeFocus ? focusedBorderWidth : borderWidth
|
||||||
|
|
||||||
|
// Left icon
|
||||||
|
DankIcon {
|
||||||
|
id: leftIcon
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
name: leftIconName
|
||||||
|
size: leftIconSize
|
||||||
|
color: textInput.activeFocus ? leftIconFocusedColor : leftIconColor
|
||||||
|
visible: leftIconName !== ""
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
id: textInput
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: root.leftPadding
|
||||||
|
anchors.rightMargin: root.rightPadding
|
||||||
|
anchors.topMargin: root.topPadding
|
||||||
|
anchors.bottomMargin: root.bottomPadding
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
selectByMouse: true
|
||||||
|
clip: true
|
||||||
|
onTextChanged: root.textEdited()
|
||||||
|
onEditingFinished: root.editingFinished()
|
||||||
|
onAccepted: root.accepted()
|
||||||
|
onActiveFocusChanged: root.focusChanged(activeFocus)
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.IBeamCursor
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear button
|
||||||
|
Rectangle {
|
||||||
|
id: clearButton
|
||||||
|
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
radius: 12
|
||||||
|
color: clearArea.containsMouse ? Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) : "transparent"
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: showClearButton && text.length > 0
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "close"
|
||||||
|
size: 16
|
||||||
|
color: clearArea.containsMouse ? Theme.outline : Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: clearArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
textInput.text = "";
|
||||||
|
textInput.forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: placeholderLabel
|
||||||
|
|
||||||
|
anchors.fill: textInput
|
||||||
|
text: root.placeholderText
|
||||||
|
font: textInput.font
|
||||||
|
color: placeholderColor
|
||||||
|
verticalAlignment: textInput.verticalAlignment
|
||||||
|
visible: textInput.text.length === 0 && !textInput.activeFocus
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user