closing panes

This commit is contained in:
zadam 2021-05-24 22:29:49 +02:00
parent 2f5d3729de
commit 5707b7e29a
14 changed files with 94 additions and 107 deletions

View File

@ -1,12 +1,12 @@
import FlexContainer from "../widgets/containers/flex_container.js";
import GlobalMenuWidget from "../widgets/global_menu.js";
import GlobalMenuWidget from "../widgets/buttons/global_menu.js";
import TabRowWidget from "../widgets/tab_row.js";
import TitleBarButtonsWidget from "../widgets/title_bar_buttons.js";
import SidePaneContainer from "../widgets/containers/side_pane_container.js";
import NoteTreeWidget from "../widgets/note_tree.js";
import NoteTitleWidget from "../widgets/note_title.js";
import OwnedAttributeListWidget from "../widgets/type_property_widgets/owned_attribute_list.js";
import NoteActionsWidget from "../widgets/note_actions.js";
import NoteActionsWidget from "../widgets/buttons/note_actions.js";
import NoteDetailWidget from "../widgets/note_detail.js";
import CollapsibleSectionContainer from "../widgets/containers/collapsible_section_container.js";
import PromotedAttributesWidget from "../widgets/type_property_widgets/promoted_attributes.js";
@ -26,10 +26,12 @@ import RootContainer from "../widgets/containers/root_container.js";
import NoteUpdateStatusWidget from "../widgets/note_update_status.js";
import SpacerWidget from "../widgets/spacer.js";
import QuickSearchWidget from "../widgets/quick_search.js";
import ButtonWidget from "../widgets/button_widget.js";
import ProtectedSessionStatusWidget from "../widgets/protected_session_status.js";
import ButtonWidget from "../widgets/buttons/button_widget.js";
import ProtectedSessionStatusWidget from "../widgets/buttons/protected_session_status.js";
import PaneContainer from "../widgets/containers/pane_container.js";
import SidebarToggleWidget from "../widgets/sidebar_toggle.js";
import SidebarToggleWidget from "../widgets/buttons/sidebar_toggle.js";
import CreatePaneButton from "../widgets/buttons/create_pane_button.js";
import ClosePaneButton from "../widgets/buttons/close_pane_button.js";
export default class DesktopLayout {
constructor(customWidgets) {
@ -90,12 +92,9 @@ export default class DesktopLayout {
.overflowing()
.child(new NoteIconWidget())
.child(new NoteTitleWidget())
.child(new ButtonWidget()
.icon("bx-window-open bx-rotate-90")
.title("Create new pane")
.titlePlacement("bottom")
.onClick(widget => widget.triggerCommand("openNewPane", { ntxId: widget.getNtxId() }))
)
.child(new SpacerWidget(1))
.child(new ClosePaneButton())
.child(new CreatePaneButton())
)
.child(
new CollapsibleSectionContainer()

View File

@ -64,6 +64,11 @@ class NoteContext extends Component {
return appContext.tabManager.noteContexts.filter(nc => nc.ntxId === this.ntxId || nc.mainNtxId === this.ntxId);
}
isMainContext() {
// if null then this is a main context
return !this.mainNtxId;
}
getMainContext() {
if (this.mainNtxId) {
return appContext.tabManager.getNoteContextById(this.mainNtxId);

View File

@ -277,7 +277,7 @@ export default class TabManager extends Component {
await this.openContextWithNote(noteId, true);
}
activateNoteContext(ntxId, triggerEvent = true) {
async activateNoteContext(ntxId, triggerEvent = true) {
if (ntxId === this.activeNtxId) {
return;
}
@ -285,7 +285,7 @@ export default class TabManager extends Component {
this.activeNtxId = ntxId;
if (triggerEvent) {
this.triggerEvent('activeContextChanged', {
await this.triggerEvent('activeContextChanged', {
noteContext: this.getNoteContextById(ntxId)
});
}
@ -296,20 +296,23 @@ export default class TabManager extends Component {
}
async removeNoteContext(ntxId) {
const mainNoteContextToRemove = this.getNoteContextById(ntxId).getMainContext();
const noteContextToRemove = this.getNoteContextById(ntxId);
// close dangling autocompletes after closing the tab
$(".aa-input").autocomplete("close");
const ntxIdsToRemove = mainNoteContextToRemove.getSubContexts().map(nc => nc.ntxId);
const ntxIdsToRemove = noteContextToRemove.getSubContexts().map(nc => nc.ntxId);
await this.triggerEvent('beforeTabRemove', { ntxIds: ntxIdsToRemove });
if (this.mainNoteContexts.length <= 1) {
if (!noteContextToRemove.isMainContext()) {
await this.activateNoteContext(noteContextToRemove.getMainContext().ntxId);
}
else if (this.mainNoteContexts.length <= 1) {
await this.openAndActivateEmptyTab();
}
else if (ntxIdsToRemove.includes(this.activeNtxId)) {
const idx = this.mainNoteContexts.findIndex(nc => nc.ntxId === mainNoteContextToRemove.ntxId);
const idx = this.mainNoteContexts.findIndex(nc => nc.ntxId === noteContextToRemove.ntxId);
if (idx === this.mainNoteContexts.length - 1) {
this.activatePreviousTabCommand();

View File

@ -1,4 +1,4 @@
import BasicWidget from "./basic_widget.js";
import NoteContextAwareWidget from "../note_context_aware_widget.js";
const TPL = `
<span class="button-widget"
@ -8,7 +8,11 @@ const TPL = `
</span>
`;
export default class ButtonWidget extends BasicWidget {
export default class ButtonWidget extends NoteContextAwareWidget {
isEnabled() {
return true;
}
constructor() {
super();

View File

@ -0,0 +1,18 @@
import ButtonWidget from "./button_widget.js";
export default class ClosePaneButton extends ButtonWidget {
isEnabled() {
return super.isEnabled()
// main note context should not be closeable
&& this.noteContext && !!this.noteContext.mainNtxId;
}
constructor() {
super();
this.icon("bx-x")
.title("Close this pane")
.titlePlacement("bottom")
.onClick(widget => widget.triggerCommand("closeThisPane", { ntxId: widget.getNtxId() }));
}
}

View File

@ -0,0 +1,12 @@
import ButtonWidget from "./button_widget.js";
export default class CreatePaneButton extends ButtonWidget {
constructor() {
super();
this.icon("bx-window-open bx-rotate-90")
.title("Create new pane")
.titlePlacement("bottom")
.onClick(widget => widget.triggerCommand("openNewPane", { ntxId: widget.getNtxId() }));
}
}

View File

@ -1,5 +1,5 @@
import BasicWidget from "./basic_widget.js";
import utils from "../services/utils.js";
import BasicWidget from "../basic_widget.js";
import utils from "../../services/utils.js";
const TPL = `
<div class="global-menu-wrapper">
@ -105,7 +105,7 @@ export default class GlobalMenuWidget extends BasicWidget {
this.overflowing();
this.$widget.find(".show-about-dialog-button").on('click',
() => import("../dialogs/about.js").then(d => d.showDialog()));
() => import("../../dialogs/about.js").then(d => d.showDialog()));
this.$widget.find(".logout-button").toggle(!utils.isElectron());

View File

@ -1,6 +1,6 @@
import NoteContextAwareWidget from "./note_context_aware_widget.js";
import protectedSessionService from "../services/protected_session.js";
import utils from "../services/utils.js";
import NoteContextAwareWidget from "../note_context_aware_widget.js";
import protectedSessionService from "../../services/protected_session.js";
import utils from "../../services/utils.js";
const TPL = `
<div class="dropdown note-actions">
@ -114,11 +114,11 @@ export default class NoteActionsWidget extends NoteContextAwareWidget {
return;
}
import('../dialogs/export.js').then(d => d.showDialog(this.noteContext.notePath, 'single'));
import('../../dialogs/export.js').then(d => d.showDialog(this.noteContext.notePath, 'single'));
});
this.$importNoteButton = this.$widget.find('.import-files-button');
this.$importNoteButton.on("click", () => import('../dialogs/import.js').then(d => d.showDialog(this.noteId)));
this.$importNoteButton.on("click", () => import('../../dialogs/import.js').then(d => d.showDialog(this.noteId)));
this.$protectButton = this.$widget.find(".protect-button");
this.$protectButton.on('click', () => protectedSessionService.protectNote(this.noteId, true, false));

View File

@ -1,5 +1,5 @@
import ButtonWidget from "./button_widget.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
import protectedSessionHolder from "../../services/protected_session_holder.js";
export default class ProtectedSessionStatusWidget extends ButtonWidget {
doRender() {

View File

@ -1,6 +1,6 @@
import ButtonWidget from "./button_widget.js";
import options from "../services/options.js";
import splitService from "../services/split.js";
import options from "../../services/options.js";
import splitService from "../../services/split.js";
export default class SidebarToggleWidget extends ButtonWidget {
refreshIcon() {

View File

@ -55,6 +55,10 @@ export default class PaneContainer extends FlexContainer {
await noteContext.setEmpty();
}
closeThisPaneCommand({ntxId}) {
appContext.tabManager.removeNoteContext(ntxId);
}
activeContextChangedEvent() {
this.refresh();
}
@ -63,6 +67,16 @@ export default class PaneContainer extends FlexContainer {
this.refresh();
}
noteContextRemovedEvent({ntxIds}) {
this.children = this.children.filter(c => !ntxIds.includes(c.ntxId));
for (const ntxId of ntxIds) {
this.$widget.find(`[data-ntx-id="${ntxId}"]`).remove();
delete this.widgets[ntxId];
}
}
async refresh() {
this.toggleExt(true);
}

View File

@ -9,7 +9,7 @@ const TPL = `
<div class="note-title-container">
<style>
.note-title-container {
flex-grow: 100;
flex-grow: 1000;
}
.note-title-container input.note-title {

View File

@ -1,67 +0,0 @@
import options from "../services/options.js";
import splitService from "../services/split.js";
import BasicWidget from "./basic_widget.js";
const TPL = `
<div>
<style>
.hide-left-pane-button, .show-left-pane-button {
position: fixed;
bottom: 10px;
left: 10px;
z-index: 100;
}
</style>
<button class="hide-left-pane-button btn btn-sm icon-button bx bx-chevrons-left" title="Hide sidebar"></button>
<button class="show-left-pane-button btn btn-sm icon-button bx bx-chevrons-right" title="Show sidebar"></button>
<button class="hide-right-pane-button btn btn-sm icon-button bx bx-chevrons-right" title="Hide sidebar"></button>
<button class="show-right-pane-button btn btn-sm icon-button bx bx-chevrons-left" title="Show sidebar"></button>
</div>
`;
export default class SidePaneToggles extends BasicWidget {
constructor() {
super();
this.paneVisible = {};
}
doRender() {
this.$widget = $(TPL);
this.$widget.find(".show-right-pane-button").on('click', () => this.toggleAndSave('right', true));
this.$widget.find(".hide-right-pane-button").on('click', () => this.toggleAndSave('right', false));
this.$widget.find(".show-left-pane-button").on('click', () => this.toggleAndSave('left', true));
this.$widget.find(".hide-left-pane-button").on('click', () => this.toggleAndSave('left', false));
this.$widget.css("contain", "none"); // this widget overflows so we need to override default containment
}
toggleSidebar(side, show) {
$(`#${side}-pane`).toggle(show);
this.$widget.find(`.show-${side}-pane-button`).toggle(!show);
this.$widget.find(`.hide-${side}-pane-button`).toggle(show);
this.paneVisible[side] = show;
}
async toggleAndSave(side, show) {
await options.save(`${side}PaneVisible`, show.toString());
this.toggleSidebar(side, show);
splitService.setupSplit(this.paneVisible.left, this.paneVisible.right);
this.triggerEvent('sidebarVisibilityChanged', {side, show});
}
initialRenderCompleteEvent() {
this.toggleSidebar('left', options.is('leftPaneVisible'));
this.toggleSidebar('right', options.is('rightPaneVisible'));
splitService.setupSplit(this.paneVisible.left, this.paneVisible.right);
}
}

View File

@ -1,17 +1,16 @@
import BasicWidget from "./basic_widget.js";
const TPL = `
<div class="spacer">
<style>
.spacer {
flex-grow: 1000;
}
</style>
</div>
`;
const TPL = `<div class="spacer"></div>`;
export default class SpacerWidget extends BasicWidget {
constructor(growIndex = 1000) {
super();
this.growIndex = growIndex;
}
doRender() {
this.$widget = $(TPL);
this.$widget.css("flex-grow", this.growIndex)
}
}