mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 13:56:32 +08:00
feat(前端界面): 右侧栏分为文档与字体两页
This commit is contained in:
1 parent
f77899e576
commit
17383adab6
3 files changed
+67
-15
No files matched your search
+11
-4
@@ -802,16 +802,19 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<aside class="meta-panel">
|
<aside class="meta-panel">
|
||||||
<div class="panel-row">
|
<div id="metaTabs" class="navigation-tabs">
|
||||||
<div class="panel-title compact">文档</div>
|
<button id="documentMetaTab" type="button" data-selected="true">文档</button>
|
||||||
<div class="panel-actions">
|
<button id="fontsMetaTab" type="button" data-selected="false" tabindex="-1">字体</button>
|
||||||
|
</div>
|
||||||
|
<div id="metaContent" class="meta-content">
|
||||||
|
<div id="metaDocumentPanel">
|
||||||
|
<div class="panel-actions meta-document-actions">
|
||||||
<button id="resourceManageButton" class="small-button" type="button" disabled>资源</button>
|
<button id="resourceManageButton" class="small-button" type="button" disabled>资源</button>
|
||||||
<button id="settingsButton" class="small-button" type="button" disabled>配置</button>
|
<button id="settingsButton" class="small-button" type="button" disabled>配置</button>
|
||||||
<button id="invoiceButton" class="small-button" type="button" hidden disabled>发票</button>
|
<button id="invoiceButton" class="small-button" type="button" hidden disabled>发票</button>
|
||||||
<button id="documentManageButton" class="small-button" type="button" hidden>管理</button>
|
<button id="documentManageButton" class="small-button" type="button" hidden>管理</button>
|
||||||
<button id="versionManageButton" class="small-button" type="button" hidden>版本</button>
|
<button id="versionManageButton" class="small-button" type="button" hidden>版本</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div id="editNotice" class="font-permission-hint" hidden></div>
|
<div id="editNotice" class="font-permission-hint" hidden></div>
|
||||||
<div id="documentRow" class="document-row" hidden>
|
<div id="documentRow" class="document-row" hidden>
|
||||||
<select id="documentSelect" class="document-select" title="切换文档"></select>
|
<select id="documentSelect" class="document-select" title="切换文档"></select>
|
||||||
@@ -916,6 +919,8 @@
|
|||||||
<div class="panel-row"><div id="structurePanelTitle" class="panel-title compact">结构</div><div class="panel-actions"><span id="structureSummary" class="count-pill">0</span><button id="structureManage" class="small-button" type="button" hidden>管理</button></div></div>
|
<div class="panel-row"><div id="structurePanelTitle" class="panel-title compact">结构</div><div class="panel-actions"><span id="structureSummary" class="count-pill">0</span><button id="structureManage" class="small-button" type="button" hidden>管理</button></div></div>
|
||||||
<div id="structureList" class="structure-list"></div>
|
<div id="structureList" class="structure-list"></div>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
|
<div id="metaFontsPanel" hidden>
|
||||||
<section class="doc-font-panel">
|
<section class="doc-font-panel">
|
||||||
<div class="panel-row">
|
<div class="panel-row">
|
||||||
<div id="docFontPanelTitle" class="panel-title compact">文档字体</div>
|
<div id="docFontPanelTitle" class="panel-title compact">文档字体</div>
|
||||||
@@ -936,6 +941,8 @@
|
|||||||
<div id="fontPermissionHint" class="font-permission-hint" hidden>系统字体未授权</div>
|
<div id="fontPermissionHint" class="font-permission-hint" hidden>系统字体未授权</div>
|
||||||
<div id="fontList" class="font-list"></div>
|
<div id="fontList" class="font-list"></div>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
+17
-4
@@ -1843,7 +1843,7 @@ body[data-hide-meta] .meta-panel {
|
|||||||
.search-results,
|
.search-results,
|
||||||
.editor-toolbar,
|
.editor-toolbar,
|
||||||
.document-list,
|
.document-list,
|
||||||
.meta-panel {
|
.meta-content {
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scrollbar-color: var(--line-strong) transparent;
|
scrollbar-color: var(--line-strong) transparent;
|
||||||
}
|
}
|
||||||
@@ -1859,13 +1859,15 @@ body[data-hide-meta] .meta-panel {
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-list-panel {
|
.page-list-panel,
|
||||||
|
.meta-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation-content {
|
.navigation-content,
|
||||||
|
.meta-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@@ -1889,6 +1891,17 @@ body[data-hide-meta] .meta-panel {
|
|||||||
border-left: 1px solid var(--line);
|
border-left: 1px solid var(--line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.meta-document-actions {
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#metaFontsPanel > .doc-font-panel {
|
||||||
|
margin-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.meta-panel .panel-row {
|
.meta-panel .panel-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto minmax(0, 1fr);
|
grid-template-columns: auto minmax(0, 1fr);
|
||||||
@@ -4568,7 +4581,7 @@ audio.page-media {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body[data-hide-meta] .meta-panel {
|
body[data-hide-meta] .meta-panel {
|
||||||
display: block;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
body[data-hide-pages] .page-list-panel {
|
body[data-hide-pages] .page-list-panel {
|
||||||
|
|||||||
+39
-7
@@ -183,6 +183,8 @@ function createDocumentState() {
|
|||||||
encryptionChanged: false,
|
encryptionChanged: false,
|
||||||
showPages: !COMPACT_LAYOUT.matches,
|
showPages: !COMPACT_LAYOUT.matches,
|
||||||
showMeta: !COMPACT_LAYOUT.matches,
|
showMeta: !COMPACT_LAYOUT.matches,
|
||||||
|
metaTab: "document",
|
||||||
|
metaScroll: {document: 0, fonts: 0},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,6 +594,12 @@ const el = {
|
|||||||
searchNext: document.querySelector("#searchNext"),
|
searchNext: document.querySelector("#searchNext"),
|
||||||
searchResults: document.querySelector("#searchResults"),
|
searchResults: document.querySelector("#searchResults"),
|
||||||
metaPanel: document.querySelector(".meta-panel"),
|
metaPanel: document.querySelector(".meta-panel"),
|
||||||
|
metaTabs: document.querySelector("#metaTabs"),
|
||||||
|
metaContent: document.querySelector("#metaContent"),
|
||||||
|
documentMetaTab: document.querySelector("#documentMetaTab"),
|
||||||
|
fontsMetaTab: document.querySelector("#fontsMetaTab"),
|
||||||
|
metaDocumentPanel: document.querySelector("#metaDocumentPanel"),
|
||||||
|
metaFontsPanel: document.querySelector("#metaFontsPanel"),
|
||||||
renderVectorButton: document.querySelector("#renderVectorButton"),
|
renderVectorButton: document.querySelector("#renderVectorButton"),
|
||||||
renderRasterButton: document.querySelector("#renderRasterButton"),
|
renderRasterButton: document.querySelector("#renderRasterButton"),
|
||||||
refreshAppButton: document.querySelector("#refreshAppButton"),
|
refreshAppButton: document.querySelector("#refreshAppButton"),
|
||||||
@@ -1735,17 +1743,22 @@ document.querySelector("#objectActionsButton").addEventListener("click", async (
|
|||||||
});
|
});
|
||||||
el.outlinesTab.addEventListener("click", () => showNavigation(el.outlinesTab));
|
el.outlinesTab.addEventListener("click", () => showNavigation(el.outlinesTab));
|
||||||
el.searchTab.addEventListener("click", focusSearch);
|
el.searchTab.addEventListener("click", focusSearch);
|
||||||
el.navigationTabs.addEventListener("keydown", (event) => {
|
el.documentMetaTab.addEventListener("click", () => showMetaSection(el.documentMetaTab));
|
||||||
|
el.fontsMetaTab.addEventListener("click", () => showMetaSection(el.fontsMetaTab));
|
||||||
|
for (const [container, buttons, show] of [
|
||||||
|
[el.navigationTabs, [el.pagesTab, el.outlinesTab, el.annotationsTab, el.searchTab], showNavigation],
|
||||||
|
[el.metaTabs, [el.documentMetaTab, el.fontsMetaTab], showMetaSection],
|
||||||
|
]) container.addEventListener("keydown", (event) => {
|
||||||
if (event.isComposing || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
|
if (event.isComposing || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
|
if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const tabs = [el.pagesTab, el.outlinesTab, el.annotationsTab, el.searchTab].filter((tab) => !tab.hidden);
|
const tabs = buttons.filter((tab) => !tab.hidden);
|
||||||
const current = tabs.indexOf(event.target);
|
const current = tabs.indexOf(event.target);
|
||||||
const index = event.key === "Home" ? 0 : event.key === "End" ? tabs.length - 1
|
const index = event.key === "Home" ? 0 : event.key === "End" ? tabs.length - 1
|
||||||
: (current + (event.key === "ArrowRight" ? 1 : -1) + tabs.length) % tabs.length;
|
: (current + (event.key === "ArrowRight" ? 1 : -1) + tabs.length) % tabs.length;
|
||||||
showNavigation(tabs[index]);
|
show(tabs[index]);
|
||||||
tabs[index].focus({ preventScroll: true });
|
tabs[index].focus({ preventScroll: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -2781,8 +2794,9 @@ function detachDocumentView() {
|
|||||||
window.clearTimeout(wasmRecoveryTimer);
|
window.clearTimeout(wasmRecoveryTimer);
|
||||||
wasmRecoveryTimer = 0;
|
wasmRecoveryTimer = 0;
|
||||||
const selection = canvasEditor.selected;
|
const selection = canvasEditor.selected;
|
||||||
|
state.metaScroll[state.metaTab] = el.metaContent.scrollTop;
|
||||||
tab.view = { anchor: state.doc ? scaleAnchor() : null, navigation: el.navigationTabs.querySelector('[data-selected="true"]'),
|
tab.view = { anchor: state.doc ? scaleAnchor() : null, navigation: el.navigationTabs.querySelector('[data-selected="true"]'),
|
||||||
navigationTop: el.navigationContent.scrollTop, metaTop: el.metaPanel.scrollTop, tool: canvasEditor.tool,
|
navigationTop: el.navigationContent.scrollTop, tool: canvasEditor.tool,
|
||||||
selection: selection ? {index: selection.index, ids: (selection.items || [selection]).map(item => item.id)} : canvasEditor.pendingSelection,
|
selection: selection ? {index: selection.index, ids: (selection.items || [selection]).map(item => item.id)} : canvasEditor.pendingSelection,
|
||||||
richClipboard: canvasEditor.richClipboard, search: el.searchInput.value };
|
richClipboard: canvasEditor.richClipboard, search: el.searchInput.value };
|
||||||
tab.view.searchStatus = state.searchRunning ? "搜索已暂停" : el.searchStatus.textContent;
|
tab.view.searchStatus = state.searchRunning ? "搜索已暂停" : el.searchStatus.textContent;
|
||||||
@@ -2943,7 +2957,6 @@ async function mountDocumentTab(tab) {
|
|||||||
if (view?.anchor) restoreScaleAnchor(view.anchor);
|
if (view?.anchor) restoreScaleAnchor(view.anchor);
|
||||||
showNavigation(view?.navigation || el.pagesTab);
|
showNavigation(view?.navigation || el.pagesTab);
|
||||||
el.navigationContent.scrollTop = view?.navigationTop || 0;
|
el.navigationContent.scrollTop = view?.navigationTop || 0;
|
||||||
el.metaPanel.scrollTop = view?.metaTop || 0;
|
|
||||||
canvasEditor.setTool(view?.tool || "");
|
canvasEditor.setTool(view?.tool || "");
|
||||||
} else {
|
} else {
|
||||||
renderPageList();
|
renderPageList();
|
||||||
@@ -2954,6 +2967,7 @@ async function mountDocumentTab(tab) {
|
|||||||
}
|
}
|
||||||
renderFontList();
|
renderFontList();
|
||||||
updateFontSummary();
|
updateFontSummary();
|
||||||
|
renderMetaSections();
|
||||||
updateControls();
|
updateControls();
|
||||||
tab.controlsPending = false;
|
tab.controlsPending = false;
|
||||||
setStatus(tab.status);
|
setStatus(tab.status);
|
||||||
@@ -6517,8 +6531,10 @@ async function openDocument(options = {}) {
|
|||||||
el.viewerPanel.scrollTop = 0;
|
el.viewerPanel.scrollTop = 0;
|
||||||
el.navigationContent.scrollLeft = 0;
|
el.navigationContent.scrollLeft = 0;
|
||||||
el.navigationContent.scrollTop = 0;
|
el.navigationContent.scrollTop = 0;
|
||||||
el.metaPanel.scrollLeft = 0;
|
state.metaTab = "document";
|
||||||
el.metaPanel.scrollTop = 0;
|
state.metaScroll = {document: 0, fonts: 0};
|
||||||
|
el.metaContent.scrollLeft = 0;
|
||||||
|
renderMetaSections();
|
||||||
}
|
}
|
||||||
applyFit(false);
|
applyFit(false);
|
||||||
if (options.keepPreview) {
|
if (options.keepPreview) {
|
||||||
@@ -11618,6 +11634,22 @@ function focusSearch() {
|
|||||||
el.searchInput.select();
|
el.searchInput.select();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showMetaSection(selected) {
|
||||||
|
state.metaScroll[state.metaTab] = el.metaContent.scrollTop;
|
||||||
|
state.metaTab = selected === el.fontsMetaTab ? "fonts" : "document";
|
||||||
|
renderMetaSections();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderMetaSections() {
|
||||||
|
for (const [tab, panel, name] of [[el.documentMetaTab, el.metaDocumentPanel, "document"], [el.fontsMetaTab, el.metaFontsPanel, "fonts"]]) {
|
||||||
|
const active = name === state.metaTab;
|
||||||
|
panel.hidden = !active;
|
||||||
|
tab.setAttribute("data-selected", String(active));
|
||||||
|
tab.tabIndex = active ? 0 : -1;
|
||||||
|
}
|
||||||
|
el.metaContent.scrollTop = state.metaScroll[state.metaTab];
|
||||||
|
}
|
||||||
|
|
||||||
function showNavigation(selected) {
|
function showNavigation(selected) {
|
||||||
const scrollTop = el.navigationContent.scrollTop;
|
const scrollTop = el.navigationContent.scrollTop;
|
||||||
for (const [tab, panel] of [[el.pagesTab, el.pageList], [el.outlinesTab, el.outlineList], [el.annotationsTab, el.annotationsPanel], [el.searchTab, el.searchPanel]]) {
|
for (const [tab, panel] of [[el.pagesTab, el.pageList], [el.outlinesTab, el.outlineList], [el.annotationsTab, el.annotationsPanel], [el.searchTab, el.searchPanel]]) {
|
||||||
|
|||||||
Reference in new issue
Block a user