feat: added widgets capture, music visualiser, bluetooth, notes
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: widget
|
||||
|
||||
readonly property var currentTab: {
|
||||
const tabs = NotepadStorageService.tabs || [];
|
||||
const index = NotepadStorageService.currentTabIndex;
|
||||
return (index >= 0 && index < tabs.length) ? tabs[index] : null;
|
||||
}
|
||||
// DMS only writes back temporary (scratch) tabs automatically; a tab backed
|
||||
// by a real file is shown read-only so edits here cannot clobber it.
|
||||
readonly property bool editable: currentTab !== null && currentTab.isTemporary === true
|
||||
property bool contentLoaded: false
|
||||
property int loadedTabId: -1
|
||||
property bool applyingRemote: false
|
||||
property bool dirty: false
|
||||
|
||||
function loadContent() {
|
||||
if (!widget.currentTab)
|
||||
return;
|
||||
|
||||
const tabId = widget.currentTab.id;
|
||||
widget.contentLoaded = false;
|
||||
NotepadStorageService.loadTabContent(NotepadStorageService.currentTabIndex, content => {
|
||||
const buffer = NotepadStorageService.getSessionBuffer(tabId);
|
||||
widget.applyingRemote = true;
|
||||
editor.text = (buffer !== undefined) ? buffer.content : content;
|
||||
widget.applyingRemote = false;
|
||||
widget.loadedTabId = tabId;
|
||||
widget.contentLoaded = true;
|
||||
widget.dirty = false;
|
||||
});
|
||||
}
|
||||
|
||||
function save() {
|
||||
if (!widget.contentLoaded || !widget.editable || widget.loadedTabId < 0)
|
||||
return;
|
||||
|
||||
NotepadStorageService.setSessionBuffer(widget.loadedTabId, editor.text, editor.text);
|
||||
NotepadStorageService.saveTabContent(NotepadStorageService.currentTabIndex, editor.text);
|
||||
widget.dirty = false;
|
||||
}
|
||||
|
||||
Ref {
|
||||
service: NotepadStorageService
|
||||
}
|
||||
|
||||
Component.onCompleted: widget.loadContent()
|
||||
Component.onDestruction: {
|
||||
if (widget.dirty)
|
||||
widget.save();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: NotepadStorageService
|
||||
|
||||
function onCurrentTabIndexChanged() {
|
||||
widget.loadContent();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: saveTimer
|
||||
|
||||
interval: 900
|
||||
repeat: false
|
||||
onTriggered: widget.save()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: editorFrame
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: footer.top
|
||||
anchors.bottomMargin: Theme.spacingXS
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.withAlpha(Theme.surfaceLight, Theme.popupTransparency)
|
||||
border.color: editor.activeFocus ? Theme.primary : Theme.outlineLight
|
||||
border.width: editor.activeFocus ? 1 : Theme.layerOutlineWidth
|
||||
clip: true
|
||||
|
||||
DankFlickable {
|
||||
id: editorFlick
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingS
|
||||
contentWidth: width
|
||||
contentHeight: editor.implicitHeight
|
||||
clip: true
|
||||
|
||||
TextArea {
|
||||
id: editor
|
||||
|
||||
width: editorFlick.width
|
||||
readOnly: !widget.editable
|
||||
wrapMode: TextArea.Wrap
|
||||
selectByMouse: true
|
||||
placeholderText: widget.editable ? "Notes, seeds, codes…" : "Open the DMS notepad to edit this tab"
|
||||
color: Theme.surfaceText
|
||||
placeholderTextColor: Theme.surfaceVariantText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.family: Theme.monoFontFamily
|
||||
background: null
|
||||
|
||||
onTextChanged: {
|
||||
if (widget.applyingRemote || !widget.contentLoaded || !widget.editable)
|
||||
return;
|
||||
|
||||
widget.dirty = true;
|
||||
saveTimer.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: footer
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
height: 26
|
||||
|
||||
StyledText {
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: openButton.left
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
text: {
|
||||
if (!widget.currentTab)
|
||||
return "No notepad tab";
|
||||
if (!widget.editable)
|
||||
return widget.currentTab.title + " · read-only here";
|
||||
return widget.currentTab.title + (widget.dirty ? " · saving…" : " · saved");
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: openButton
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: openRow.width + Theme.spacingM * 2
|
||||
height: 24
|
||||
radius: Theme.cornerRadius
|
||||
color: openArea.containsMouse ? Theme.surfaceHover : "transparent"
|
||||
|
||||
Row {
|
||||
id: openRow
|
||||
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
DankIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: "open_in_new"
|
||||
size: Theme.fontSizeMedium
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "Full notepad"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: openArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
widget.save();
|
||||
Quickshell.execDetached(["dms", "ipc", "call", "notepad", "toggle"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user