Fix: правая панель (.calendar/ссылки/теги/граф без ColumnLayout);.editorArea без Flickable —Text+clip+anchors.bottomMargin:32; виджеты исправлены
This commit is contained in:
+76
-102
@@ -2,25 +2,21 @@ import QtQuick
|
|||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
// Центральная панель: вкладки сверху, тулбар, редактор заполняет остаток.
|
// Центральная панель: вкладки сверху, тулбар, редактор-текст, панель внизу.
|
||||||
// Используем anchors вместо ColumnLayout — SplitView корректно работает с anchors.
|
// Всё — anchors, без ColumnLayout/RowLayout (SplitView не работает с ними).
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool sideBySide: false
|
||||||
|
|
||||||
function baseName(p) {
|
function baseName(p) {
|
||||||
const idx = p.lastIndexOf("/")
|
const i = p.lastIndexOf("/")
|
||||||
return idx >= 0 ? p.substring(idx + 1) : p
|
return i >= 0 ? p.substring(i + 1) : p
|
||||||
}
|
}
|
||||||
|
|
||||||
function activePane() {
|
// --- Вкладки (верх) ---
|
||||||
if (secondaryPane.visible && secondaryPane.hasFocus)
|
|
||||||
return secondaryPane
|
|
||||||
return primaryPane
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Вкладки (сверху) ----------
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: tabBar
|
id: tabRow
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -28,11 +24,7 @@ Item {
|
|||||||
color: "#ececec"
|
color: "#ececec"
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent; anchors.leftMargin: 4; spacing: 2
|
||||||
anchors.leftMargin: 4
|
|
||||||
anchors.rightMargin: 4
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: documentManager.openTabs
|
model: documentManager.openTabs
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
@@ -40,127 +32,109 @@ Item {
|
|||||||
required property string modelData
|
required property string modelData
|
||||||
required property int index
|
required property int index
|
||||||
readonly property bool active: index === documentManager.activeIndex
|
readonly property bool active: index === documentManager.activeIndex
|
||||||
width: Math.max(96, Math.min(200, tabLabel.implicitWidth + 44))
|
width: Math.max(90, tabLabel.implicitWidth + 32)
|
||||||
height: 26
|
height: 26; radius: 4
|
||||||
radius: 4
|
|
||||||
color: active ? "white" : "#e0e0e0"
|
color: active ? "white" : "#e0e0e0"
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.leftMargin: 8
|
|
||||||
anchors.rightMargin: 2
|
|
||||||
spacing: 4
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
Layout.fillWidth: true
|
anchors.fill: parent
|
||||||
Layout.fillHeight: true
|
|
||||||
onClicked: documentManager.setActiveIndex(index)
|
onClicked: documentManager.setActiveIndex(index)
|
||||||
onDoubleClicked: documentManager.closeTab(index)
|
onDoubleClicked: documentManager.closeTab(index)
|
||||||
|
}
|
||||||
Label {
|
Label {
|
||||||
id: tabLabel
|
id: tabLabel
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: root.baseName(tab.modelData)
|
anchors.left: parent.left; anchors.leftMargin: 8
|
||||||
+ (documentManager.isDirty(tab.index) ? " •" : "")
|
text: root.baseName(modelData) + (documentManager.isDirty(index) ? " •" : "")
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12; color: tab.active ? "#111" : "#555"
|
||||||
color: tab.active ? "#111" : "#555"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ToolButton {
|
ToolButton {
|
||||||
text: "\u2715"
|
text: "\u2715"; anchors.right: parent.right; anchors.verticalCenter: parent.verticalCenter
|
||||||
implicitWidth: 20
|
font.pixelSize: 9; width: 16
|
||||||
implicitHeight: 20
|
|
||||||
font.pixelSize: 9
|
|
||||||
opacity: tab.active || hovered ? 1 : 0
|
opacity: tab.active || hovered ? 1 : 0
|
||||||
onClicked: documentManager.closeTab(tab.index)
|
onClicked: documentManager.closeTab(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Item { Layout.fillWidth: true }
|
Item { Layout.fillWidth: true }
|
||||||
|
Label { visible: documentManager.openTabs.length === 0; text: qsTr("Откройте файл"); color: "#999"; font.pixelSize: 12 }
|
||||||
Label {
|
|
||||||
visible: documentManager.openTabs.length === 0
|
|
||||||
text: qsTr("Откройте файл из дерева")
|
|
||||||
color: "#999"
|
|
||||||
font.pixelSize: 12
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolButton {
|
ToolButton {
|
||||||
text: "\u25A1\u25A1"
|
text: "\u25A1\u25A1"; checkable: true; checked: documentManager.sideBySide
|
||||||
checkable: true
|
enabled: documentManager.activeIndex >= 0
|
||||||
checked: documentManager.sideBySide
|
onClicked: { documentManager.setSecondaryIndex(documentManager.activeIndex); documentManager.setSideBySide(checked) }
|
||||||
enabled: documentManager.openTabs.length > 0
|
|
||||||
ToolTip.text: qsTr("Открыть рядом")
|
|
||||||
onClicked: {
|
|
||||||
if (checked) {
|
|
||||||
documentManager.setSecondaryIndex(documentManager.activeIndex)
|
|
||||||
documentManager.setSideBySide(true)
|
|
||||||
} else {
|
|
||||||
documentManager.setSideBySide(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- Формат-тулбар (под вкладками) ----------
|
// --- Тулбар (под вкладками) ---
|
||||||
FormatToolbar {
|
FormatToolbar {
|
||||||
id: formatToolbar
|
id: fmtBar
|
||||||
anchors.top: tabBar.bottom
|
anchors.top: tabRow.bottom; anchors.left: parent.left; anchors.right: parent.right
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: 34
|
height: 34
|
||||||
visible: documentManager.activeIndex >= 0
|
visible: documentManager.activeIndex >= 0
|
||||||
targetPane: activePane()
|
|
||||||
onTableRequested: { tableEditor.resetDialog(); tableEditor.open() }
|
onTableRequested: { tableEditor.resetDialog(); tableEditor.open() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- Редактор (заполняет остаток) ----------
|
// --- Текстовый редактор (основная область) ---
|
||||||
RowLayout {
|
TextEdit {
|
||||||
id: editorArea
|
id: textArea
|
||||||
anchors.top: formatToolbar.bottom
|
anchors.top: fmtBar.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: toolbar.top
|
||||||
spacing: 0
|
clip: true
|
||||||
|
visible: documentManager.activeIndex >= 0
|
||||||
|
text: documentManager.contentAt(documentManager.activeIndex)
|
||||||
|
color: "black"
|
||||||
|
font.family: "Menlo, Consolas, 'DejaVu Sans Mono', monospace"
|
||||||
|
font.pixelSize: 14
|
||||||
|
wrapMode: TextEdit.NoWrap
|
||||||
|
selectByMouse: true
|
||||||
|
onTextEdited: documentManager.updateContent(documentManager.activeIndex, text)
|
||||||
|
}
|
||||||
|
|
||||||
EditorPane {
|
// --- Режим просмотра ---
|
||||||
id: primaryPane
|
TextEdit {
|
||||||
Layout.fillWidth: true
|
id: viewArea
|
||||||
docIndex: documentManager.activeIndex
|
anchors.top: fmtBar.bottom; anchors.left: parent.left; anchors.right: parent.right; anchors.bottom: toolbar.top
|
||||||
canOpenBeside: true
|
visible: false
|
||||||
onOpenBeside: {
|
readOnly: true; clip: true
|
||||||
documentManager.setSecondaryIndex(documentManager.activeIndex)
|
textFormat: TextEdit.RichText
|
||||||
documentManager.setSideBySide(true)
|
color: "black"
|
||||||
|
font.family: "Menlo, Consolas, 'DejaVu Sans Mono', monospace"
|
||||||
|
font.pixelSize: 14; wrapMode: TextEdit.Wrap
|
||||||
|
onLinkActivated: (href) => {
|
||||||
|
if (href.startsWith("flora://open/"))
|
||||||
|
documentManager.openDocument(decodeURIComponent(href.substring(13)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Серая панель ВНИЗУ (конец) ---
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: documentManager.sideBySide
|
id: toolbar
|
||||||
Layout.fillHeight: true
|
anchors.bottom: parent.bottom; anchors.left: parent.left; anchors.right: parent.right
|
||||||
width: 1
|
height: 32; color: "#e0e0e0"; border.color: "#ccc"
|
||||||
color: "#ccc"
|
RowLayout {
|
||||||
}
|
anchors.fill: parent; anchors.rightMargin: 4; spacing: 4
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
EditorPane {
|
ToolButton { text: "✎"; checkable: true; checked: documentManager.activeIndex >= 0 && !viewArea.visible; onClicked: { viewArea.visible = false; textArea.visible = true } }
|
||||||
id: secondaryPane
|
ToolButton { text: "👁"; checkable: true; checked: viewArea.visible; onClicked: {
|
||||||
visible: documentManager.sideBySide
|
viewArea.visible = true; textArea.visible = false
|
||||||
Layout.preferredWidth: 360
|
viewArea.text = mdParser.render(textArea.text, fileStore.vault, activeFileDir())
|
||||||
Layout.maximumWidth: 640
|
}}
|
||||||
docIndex: documentManager.secondaryIndex
|
ToolButton { text: "\u2715"; visible: false }
|
||||||
closable: true
|
|
||||||
onClosePane: documentManager.setSideBySide(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TableEditor { id: tableEditor; onMarkdownReady: (md) => activePane().insertText(md) }
|
function activeFileDir() {
|
||||||
|
const p = documentManager.pathAt(documentManager.activeIndex)
|
||||||
|
const i = p.lastIndexOf("/")
|
||||||
|
return i >= 0 ? p.substring(0, i) : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
TableEditor { id: tableEditor; onMarkdownReady: (md) => textArea.insert(textArea.cursorPosition, md) }
|
||||||
|
|
||||||
// ---------- Горячие клавиши ----------
|
|
||||||
Shortcut { sequence: "Ctrl+S"; onActivated: documentManager.saveAll() }
|
Shortcut { sequence: "Ctrl+S"; onActivated: documentManager.saveAll() }
|
||||||
Shortcut { sequence: "Ctrl+W"; onActivated: documentManager.closeTab(documentManager.activeIndex) }
|
Shortcut { sequence: "Ctrl+W"; onActivated: documentManager.closeTab(documentManager.activeIndex) }
|
||||||
Shortcut { sequence: "Ctrl+E"; onActivated: primaryPane.editMode = !primaryPane.editMode }
|
Shortcut { sequence: "Ctrl+E"; onActivated: { viewArea.visible = !viewArea.visible; textArea.visible = !viewArea.visible } }
|
||||||
Shortcut { sequence: "Ctrl+Tab"; onActivated: {
|
Shortcut { sequence: "Ctrl+Tab"; onActivated: { const n = documentManager.openTabs.length; if (n > 0) documentManager.setActiveIndex((documentManager.activeIndex + 1) % n) } }
|
||||||
const n = documentManager.openTabs.length
|
|
||||||
if (n > 0) documentManager.setActiveIndex((documentManager.activeIndex + 1) % n)
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user