mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-07 22:15:38 -05:00
Add font override options in Notepad
This commit is contained in:
@@ -30,6 +30,10 @@ PanelWindow {
|
||||
property string currentContent: ""
|
||||
property string lastSavedContent: ""
|
||||
property bool contentLoaded: false
|
||||
property bool showSettingsMenu: false
|
||||
property var cachedFontFamilies: []
|
||||
property var cachedMonoFamilies: []
|
||||
property bool fontsEnumerated: false
|
||||
|
||||
function hasUnsavedChanges() {
|
||||
if (!currentTab || !contentLoaded) {
|
||||
@@ -40,8 +44,6 @@ PanelWindow {
|
||||
if (currentTab.isTemporary) {
|
||||
return textArea.text.length > 0
|
||||
}
|
||||
|
||||
// For non-temporary files, show unsaved if content differs from last saved state
|
||||
return textArea.text !== lastSavedContent
|
||||
}
|
||||
|
||||
@@ -59,6 +61,54 @@ PanelWindow {
|
||||
return false
|
||||
}
|
||||
|
||||
function enumerateFonts() {
|
||||
var fonts = ["Default"]
|
||||
var availableFonts = Qt.fontFamilies()
|
||||
var rootFamilies = []
|
||||
var seenFamilies = new Set()
|
||||
for (var i = 0; i < availableFonts.length; i++) {
|
||||
var fontName = availableFonts[i]
|
||||
if (fontName.startsWith("."))
|
||||
continue
|
||||
|
||||
if (fontName === SettingsData.defaultFontFamily)
|
||||
continue
|
||||
|
||||
var rootName = fontName.replace(/ (Thin|Extra Light|Light|Regular|Medium|Semi Bold|Demi Bold|Bold|Extra Bold|Black|Heavy)$/i, "").replace(/ (Italic|Oblique|Condensed|Extended|Narrow|Wide)$/i,
|
||||
"").replace(/ (UI|Display|Text|Mono|Sans|Serif)$/i, function (match, suffix) {
|
||||
return match
|
||||
}).trim()
|
||||
if (!seenFamilies.has(rootName) && rootName !== "") {
|
||||
seenFamilies.add(rootName)
|
||||
rootFamilies.push(rootName)
|
||||
}
|
||||
}
|
||||
cachedFontFamilies = fonts.concat(rootFamilies.sort())
|
||||
var monoFonts = ["Default"]
|
||||
var monoFamilies = []
|
||||
var seenMonoFamilies = new Set()
|
||||
for (var j = 0; j < availableFonts.length; j++) {
|
||||
var fontName2 = availableFonts[j]
|
||||
if (fontName2.startsWith("."))
|
||||
continue
|
||||
|
||||
if (fontName2 === SettingsData.defaultMonoFontFamily)
|
||||
continue
|
||||
|
||||
var lowerName = fontName2.toLowerCase()
|
||||
if (lowerName.includes("mono") || lowerName.includes("code") || lowerName.includes("console") || lowerName.includes("terminal") || lowerName.includes("courier") || lowerName.includes("dejavu sans mono") || lowerName.includes(
|
||||
"jetbrains") || lowerName.includes("fira") || lowerName.includes("hack") || lowerName.includes("source code") || lowerName.includes("ubuntu mono") || lowerName.includes("cascadia")) {
|
||||
var rootName2 = fontName2.replace(/ (Thin|Extra Light|Light|Regular|Medium|Semi Bold|Demi Bold|Bold|Extra Bold|Black|Heavy)$/i, "").replace(/ (Italic|Oblique|Condensed|Extended|Narrow|Wide)$/i, "").trim()
|
||||
if (!seenMonoFamilies.has(rootName2) && rootName2 !== "") {
|
||||
seenMonoFamilies.add(rootName2)
|
||||
monoFamilies.push(rootName2)
|
||||
}
|
||||
}
|
||||
}
|
||||
cachedMonoFamilies = monoFonts.concat(monoFamilies.sort())
|
||||
fontsEnumerated = true
|
||||
}
|
||||
|
||||
function loadCurrentTabContent() {
|
||||
if (!currentTab) return
|
||||
|
||||
@@ -173,6 +223,12 @@ PanelWindow {
|
||||
WlrLayershell.exclusiveZone: 0
|
||||
WlrLayershell.keyboardFocus: isVisible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!fontsEnumerated) {
|
||||
enumerateFonts()
|
||||
}
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
id: contentRect
|
||||
|
||||
@@ -417,8 +473,8 @@ PanelWindow {
|
||||
TextArea {
|
||||
id: textArea
|
||||
placeholderText: qsTr("Start typing your notes here...")
|
||||
font.family: SettingsData.monoFontFamily
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.family: SettingsData.notepadUseMonospace ? SettingsData.monoFontFamily : (SettingsData.notepadFontFamily || SettingsData.fontFamily)
|
||||
font.pixelSize: SettingsData.notepadFontSize * SettingsData.fontScale
|
||||
color: Theme.surfaceText
|
||||
selectByMouse: true
|
||||
selectByKeyboard: true
|
||||
@@ -529,69 +585,85 @@ PanelWindow {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Row {
|
||||
Item {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingL
|
||||
|
||||
height: 32
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
DankActionButton {
|
||||
iconName: "save"
|
||||
iconSize: Theme.iconSize - 2
|
||||
iconColor: Theme.primary
|
||||
enabled: currentTab && (hasUnsavedChanges() || textArea.text.length > 0)
|
||||
onClicked: {
|
||||
root.fileDialogOpen = true
|
||||
saveBrowser.open()
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Save")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
}
|
||||
}
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingL
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
DankActionButton {
|
||||
iconName: "folder_open"
|
||||
iconSize: Theme.iconSize - 2
|
||||
iconColor: Theme.secondary
|
||||
onClicked: {
|
||||
if (hasUnsavedChanges()) {
|
||||
root.pendingAction = "open"
|
||||
root.confirmationDialogOpen = true
|
||||
confirmationDialog.open()
|
||||
} else {
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
DankActionButton {
|
||||
iconName: "save"
|
||||
iconSize: Theme.iconSize - 2
|
||||
iconColor: Theme.primary
|
||||
enabled: currentTab && (hasUnsavedChanges() || textArea.text.length > 0)
|
||||
onClicked: {
|
||||
root.fileDialogOpen = true
|
||||
loadBrowser.open()
|
||||
saveBrowser.open()
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Save")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Open")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
DankActionButton {
|
||||
iconName: "folder_open"
|
||||
iconSize: Theme.iconSize - 2
|
||||
iconColor: Theme.secondary
|
||||
onClicked: {
|
||||
if (hasUnsavedChanges()) {
|
||||
root.pendingAction = "open"
|
||||
root.confirmationDialogOpen = true
|
||||
confirmationDialog.open()
|
||||
} else {
|
||||
root.fileDialogOpen = true
|
||||
loadBrowser.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Open")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
DankActionButton {
|
||||
iconName: "note_add"
|
||||
iconSize: Theme.iconSize - 2
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: createNewTab()
|
||||
}
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("New")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
DankActionButton {
|
||||
iconName: "note_add"
|
||||
iconSize: Theme.iconSize - 2
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: createNewTab()
|
||||
}
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("New")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
id: settingsButton
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
iconName: "more_horiz"
|
||||
iconSize: Theme.iconSize - 2
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: showSettingsMenu = !showSettingsMenu
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,6 +717,203 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
visible: showSettingsMenu
|
||||
onClicked: showSettingsMenu = false
|
||||
z: 50
|
||||
}
|
||||
|
||||
// Settings Menu Popup
|
||||
Rectangle {
|
||||
id: settingsMenu
|
||||
visible: showSettingsMenu
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: 423
|
||||
width: 360
|
||||
height: settingsColumn.implicitHeight + Theme.spacingXL * 2
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.popupBackground()
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||
border.width: 1
|
||||
z: 100
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 4
|
||||
anchors.leftMargin: 2
|
||||
anchors.rightMargin: -2
|
||||
anchors.bottomMargin: -4
|
||||
radius: parent.radius
|
||||
color: Qt.rgba(0, 0, 0, 0.15)
|
||||
z: parent.z - 1
|
||||
}
|
||||
|
||||
Column {
|
||||
id: settingsColumn
|
||||
width: parent.width - Theme.spacingXL * 2
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.spacingXL
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 36
|
||||
color: "transparent"
|
||||
|
||||
StyledText {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: -Theme.spacingXS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "Notepad Font Settings"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: -Theme.spacingM
|
||||
width: parent.width + Theme.spacingM
|
||||
text: "Use Monospace Font"
|
||||
description: "Toggle fonts"
|
||||
checked: SettingsData.notepadUseMonospace
|
||||
onToggled: checked => {
|
||||
SettingsData.notepadUseMonospace = checked
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: visible ? (fontDropdown.height + Theme.spacingS) : 0
|
||||
color: "transparent"
|
||||
visible: !SettingsData.notepadUseMonospace
|
||||
|
||||
DankDropdown {
|
||||
id: fontDropdown
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: -Theme.spacingM
|
||||
width: parent.width + Theme.spacingM
|
||||
text: "Font Family"
|
||||
options: cachedFontFamilies
|
||||
currentValue: {
|
||||
if (!SettingsData.notepadFontFamily || SettingsData.notepadFontFamily === "")
|
||||
return "Default (Global)"
|
||||
else
|
||||
return SettingsData.notepadFontFamily
|
||||
}
|
||||
enableFuzzySearch: true
|
||||
onValueChanged: value => {
|
||||
if (value && (value.startsWith("Default") || value === "Default (Global)")) {
|
||||
SettingsData.notepadFontFamily = ""
|
||||
} else {
|
||||
SettingsData.notepadFontFamily = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: fontSizeRow.height + Theme.spacingS
|
||||
color: "transparent"
|
||||
|
||||
Row {
|
||||
id: fontSizeRow
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Column {
|
||||
width: parent.width - fontSizeControls.width - Theme.spacingM
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
StyledText {
|
||||
text: "Font Size"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: SettingsData.notepadFontSize + "px"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: fontSizeControls
|
||||
spacing: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
DankActionButton {
|
||||
buttonSize: 32
|
||||
iconName: "remove"
|
||||
iconSize: Theme.iconSizeSmall
|
||||
enabled: SettingsData.notepadFontSize > 8
|
||||
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: {
|
||||
var newSize = Math.max(8, SettingsData.notepadFontSize - 1)
|
||||
SettingsData.notepadFontSize = newSize
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 60
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
border.width: 1
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
text: SettingsData.notepadFontSize + "px"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
buttonSize: 32
|
||||
iconName: "add"
|
||||
iconSize: Theme.iconSizeSmall
|
||||
enabled: SettingsData.notepadFontSize < 48
|
||||
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: {
|
||||
var newSize = Math.min(48, SettingsData.notepadFontSize + 1)
|
||||
SettingsData.notepadFontSize = newSize
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: SettingsData.notepadUseMonospace ?
|
||||
"Using global monospace font from Settings → Personalization" :
|
||||
"Global fonts can be configured in Settings → Personalization"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceTextMedium
|
||||
wrapMode: Text.WordWrap
|
||||
opacity: 0.8
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
@@ -669,7 +938,6 @@ PanelWindow {
|
||||
pendingSaveContent = content
|
||||
saveFileView.path = filePath
|
||||
|
||||
// Use Qt.callLater to ensure path is set before calling setText
|
||||
Qt.callLater(() => {
|
||||
saveFileView.setText(pendingSaveContent)
|
||||
})
|
||||
@@ -765,7 +1033,6 @@ PanelWindow {
|
||||
if (currentTab && currentTab.title && currentTab.title !== "Untitled") {
|
||||
return currentTab.title
|
||||
} else if (currentTab && !currentTab.isTemporary && currentTab.filePath) {
|
||||
// Extract filename from path for non-temporary files
|
||||
return currentTab.filePath.split('/').pop()
|
||||
} else {
|
||||
return "note.txt"
|
||||
|
||||
Reference in New Issue
Block a user