draggable splitter on mainscreen

This commit is contained in:
Jan Prochazka
2021-02-28 09:27:57 +01:00
parent 1c0a8cad56
commit f30bd0a894
6 changed files with 77 additions and 6 deletions

View File

@@ -10,6 +10,24 @@ body {
-moz-osx-font-smoothing: grayscale;
}
.horizontal-split-handle {
background-color: var(--theme-border);
width: var(--dim-splitter-thickness);
cursor: col-resize;
}
.horizontal-split-handle:hover {
background-color: var(--theme-bg-2);
}
.vertical-split-handle {
background-color: var(--theme-border);
height: var(--dim-splitter-thickness);
cursor: row-resize;
}
.vertical-split-handle:hover {
background-color: var(--theme-bg-2);
}
/* html, body {
position: relative;
width: 100%;

View File

@@ -1,11 +1,13 @@
<script lang="ts">
<script>
import WidgetContainer from './widgets/WidgetContainer.svelte';
import WidgetIconPanel from './widgets/WidgetIconPanel.svelte';
import { currentTheme, selectedWidget, visibleCommandPalette, visibleToolbar } from './stores';
import { currentTheme, leftPanelWidth, selectedWidget, visibleCommandPalette, visibleToolbar } from './stores';
import TabsPanel from './widgets/TabsPanel.svelte';
import TabContent from './TabContent.svelte';
import CommandPalette from './commands/CommandPalette.svelte';
import Toolbar from './widgets/Toolbar.svelte';
import splitterDrag from './utility/splitterDrag';
import { update } from 'lodash';
</script>
<div class={`${$currentTheme} root`}>
@@ -24,6 +26,11 @@
<div class="content">
<TabContent />
</div>
<div
class="horizontal-split-handle splitter"
use:splitterDrag={'clientX'}
on:resizeSplitter={e => leftPanelWidth.update(x => x + e.detail)}
/>
{#if $visibleCommandPalette}
<div class="commads">
<CommandPalette />
@@ -100,4 +107,11 @@
left: 0;
right: 0;
}
.splitter {
position: absolute;
top: var(--dim-header-top);
bottom: var(--dim-statusbar-height);
left: calc(var(--dim-widget-icon-size) + var(--dim-left-panel-width));
}
</style>

View File

@@ -21,7 +21,7 @@
import { derived } from 'svelte/store';
import { onMount } from 'svelte';
import { commands, visibleCommandPalette } from '../stores';
import { clickOutside } from '../utility/clickOutside';
import clickOutside from '../utility/clickOutside';
import keycodes from '../utility/keycodes';
import registerCommand from './registerCommand';

View File

@@ -34,8 +34,9 @@ export const commands = writable({});
export const currentTheme = writableWithStorage('theme-light', 'currentTheme');
export const activeTabId = derived([openedTabs], ([$openedTabs]) => $openedTabs.find(x => x.selected)?.tabid);
export const visibleToolbar = writableWithStorage(1, 'visibleToolbar');
export const leftPanelWidth = writable(300);
subscribeCssVariable(selectedWidget, x => (x ? 1 : 0), '--dim-visible-left-panel');
subscribeCssVariable(visibleToolbar, x => (x ? 1 : 0), '--dim-visible-toolbar');
subscribeCssVariable(leftPanelWidth, x => `${x}px`, '--dim-left-panel-width');
// export const leftPanelWidth = writable(300);

View File

@@ -1,7 +1,7 @@
export function clickOutside(node) {
export default function clickOutside(node) {
const handleClick = event => {
if (node && !node.contains(event.target) && !event.defaultPrevented) {
node.dispatchEvent(new CustomEvent('clickOutside', node));
node.dispatchEvent(new CustomEvent('clickOutside'));
}
};

View File

@@ -0,0 +1,38 @@
export default function splitterDrag(node, axes) {
let resizeStart = null;
const handleResizeDown = e => {
resizeStart = e[axes];
document.addEventListener('mousemove', handleResizeMove, true);
document.addEventListener('mouseup', handleResizeEnd, true);
};
const handleResizeMove = e => {
e.preventDefault();
const diff = e[axes] - resizeStart;
resizeStart = e[axes];
node.dispatchEvent(
new CustomEvent('resizeSplitter', {
detail: diff,
})
);
};
const handleResizeEnd = e => {
e.preventDefault();
resizeStart = null;
document.removeEventListener('mousemove', handleResizeMove, true);
document.removeEventListener('mouseup', handleResizeEnd, true);
};
node.addEventListener('mousedown', handleResizeDown);
return {
destroy() {
node.removeEventListener('mousedown', handleResizeDown);
if (resizeStart != null) {
document.removeEventListener('mousemove', handleResizeMove, true);
document.removeEventListener('mouseup', handleResizeEnd, true);
}
},
};
}