mirror of
https://github.com/mathuo/dockview
synced 2025-02-02 14:35:46 +00:00
Merge pull request #308 from mathuo/230-explore-floating-groups
230 explore floating groups
This commit is contained in:
commit
430f97fd7e
@ -96,7 +96,7 @@ describe('componentFactory', () => {
|
||||
|
||||
expect(component).toHaveBeenCalled();
|
||||
|
||||
expect(componentResult instanceof component);
|
||||
expect(componentResult instanceof component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { quasiDefaultPrevented, toggleClass } from '../dom';
|
||||
import {
|
||||
getElementsByTagName,
|
||||
quasiDefaultPrevented,
|
||||
toggleClass,
|
||||
} from '../dom';
|
||||
import {
|
||||
Emitter,
|
||||
Event,
|
||||
@ -29,6 +33,9 @@ export class Overlay extends CompositeDisposable {
|
||||
private readonly _onDidChange = new Emitter<void>();
|
||||
readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||
|
||||
private readonly _onDidChangeEnd = new Emitter<void>();
|
||||
readonly onDidChangeEnd: Event<void> = this._onDidChangeEnd.event;
|
||||
|
||||
private static MINIMUM_HEIGHT = 20;
|
||||
private static MINIMUM_WIDTH = 20;
|
||||
|
||||
@ -46,9 +53,10 @@ export class Overlay extends CompositeDisposable {
|
||||
) {
|
||||
super();
|
||||
|
||||
this.addDisposables(this._onDidChange);
|
||||
this.addDisposables(this._onDidChange, this._onDidChangeEnd);
|
||||
|
||||
this._element.className = 'dv-resize-container';
|
||||
|
||||
this.setupOverlay();
|
||||
this.setupResize('top');
|
||||
this.setupResize('bottom');
|
||||
this.setupResize('left');
|
||||
@ -62,7 +70,12 @@ export class Overlay extends CompositeDisposable {
|
||||
this.options.container.appendChild(this._element);
|
||||
|
||||
// if input bad resize within acceptable boundaries
|
||||
this.renderWithinBoundaryConditions();
|
||||
this.setBounds({
|
||||
height: this.options.height,
|
||||
width: this.options.width,
|
||||
top: this.options.top,
|
||||
left: this.options.left,
|
||||
});
|
||||
}
|
||||
|
||||
setBounds(
|
||||
@ -71,7 +84,7 @@ export class Overlay extends CompositeDisposable {
|
||||
width: number;
|
||||
top: number;
|
||||
left: number;
|
||||
}>
|
||||
}> = {}
|
||||
): void {
|
||||
if (typeof bounds.height === 'number') {
|
||||
this._element.style.height = `${bounds.height}px`;
|
||||
@ -86,25 +99,11 @@ export class Overlay extends CompositeDisposable {
|
||||
this._element.style.left = `${bounds.left}px`;
|
||||
}
|
||||
|
||||
this.renderWithinBoundaryConditions();
|
||||
}
|
||||
|
||||
toJSON(): { top: number; left: number; height: number; width: number } {
|
||||
const container = this.options.container.getBoundingClientRect();
|
||||
const element = this._element.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: element.top - container.top,
|
||||
left: element.left - container.left,
|
||||
width: element.width,
|
||||
height: element.height,
|
||||
};
|
||||
}
|
||||
|
||||
renderWithinBoundaryConditions(): void {
|
||||
const containerRect = this.options.container.getBoundingClientRect();
|
||||
const overlayRect = this._element.getBoundingClientRect();
|
||||
|
||||
// region: ensure bounds within allowable limits
|
||||
|
||||
// a minimum width of minimumViewportWidth must be inside the viewport
|
||||
const xOffset = Math.max(
|
||||
0,
|
||||
@ -131,6 +130,20 @@ export class Overlay extends CompositeDisposable {
|
||||
|
||||
this._element.style.left = `${left}px`;
|
||||
this._element.style.top = `${top}px`;
|
||||
|
||||
this._onDidChange.fire();
|
||||
}
|
||||
|
||||
toJSON(): { top: number; left: number; height: number; width: number } {
|
||||
const container = this.options.container.getBoundingClientRect();
|
||||
const element = this._element.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: element.top - container.top,
|
||||
left: element.left - container.left,
|
||||
width: element.width,
|
||||
height: element.height,
|
||||
};
|
||||
}
|
||||
|
||||
setupDrag(
|
||||
@ -142,7 +155,23 @@ export class Overlay extends CompositeDisposable {
|
||||
const track = () => {
|
||||
let offset: { x: number; y: number } | null = null;
|
||||
|
||||
const iframes = [
|
||||
...getElementsByTagName('iframe'),
|
||||
...getElementsByTagName('webview'),
|
||||
];
|
||||
|
||||
for (const iframe of iframes) {
|
||||
iframe.style.pointerEvents = 'none';
|
||||
}
|
||||
|
||||
move.value = new CompositeDisposable(
|
||||
{
|
||||
dispose: () => {
|
||||
for (const iframe of iframes) {
|
||||
iframe.style.pointerEvents = 'auto';
|
||||
}
|
||||
},
|
||||
},
|
||||
addDisposableWindowListener(window, 'mousemove', (e) => {
|
||||
const containerRect =
|
||||
this.options.container.getBoundingClientRect();
|
||||
@ -191,8 +220,7 @@ export class Overlay extends CompositeDisposable {
|
||||
)
|
||||
);
|
||||
|
||||
this._element.style.left = `${left}px`;
|
||||
this._element.style.top = `${top}px`;
|
||||
this.setBounds({ top, left });
|
||||
}),
|
||||
addDisposableWindowListener(window, 'mouseup', () => {
|
||||
toggleClass(
|
||||
@ -202,7 +230,7 @@ export class Overlay extends CompositeDisposable {
|
||||
);
|
||||
|
||||
move.dispose();
|
||||
this._onDidChange.fire();
|
||||
this._onDidChangeEnd.fire();
|
||||
})
|
||||
);
|
||||
};
|
||||
@ -259,15 +287,6 @@ export class Overlay extends CompositeDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
private setupOverlay(): void {
|
||||
this._element.style.height = `${this.options.height}px`;
|
||||
this._element.style.width = `${this.options.width}px`;
|
||||
this._element.style.left = `${this.options.left}px`;
|
||||
this._element.style.top = `${this.options.top}px`;
|
||||
|
||||
this._element.className = 'dv-resize-container';
|
||||
}
|
||||
|
||||
private setupResize(
|
||||
direction:
|
||||
| 'top'
|
||||
@ -297,6 +316,15 @@ export class Overlay extends CompositeDisposable {
|
||||
originalWidth: number;
|
||||
} | null = null;
|
||||
|
||||
const iframes = [
|
||||
...getElementsByTagName('iframe'),
|
||||
...getElementsByTagName('webview'),
|
||||
];
|
||||
|
||||
for (const iframe of iframes) {
|
||||
iframe.style.pointerEvents = 'none';
|
||||
}
|
||||
|
||||
move.value = new CompositeDisposable(
|
||||
addDisposableWindowListener(window, 'mousemove', (e) => {
|
||||
const containerRect =
|
||||
@ -317,10 +345,10 @@ export class Overlay extends CompositeDisposable {
|
||||
};
|
||||
}
|
||||
|
||||
let top: number | null = null;
|
||||
let height: number | null = null;
|
||||
let left: number | null = null;
|
||||
let width: number | null = null;
|
||||
let top: number | undefined = undefined;
|
||||
let height: number | undefined = undefined;
|
||||
let left: number | undefined = undefined;
|
||||
let width: number | undefined = undefined;
|
||||
|
||||
const minimumInViewportHeight =
|
||||
this.options.minimumInViewportHeight;
|
||||
@ -431,22 +459,18 @@ export class Overlay extends CompositeDisposable {
|
||||
break;
|
||||
}
|
||||
|
||||
if (height !== null) {
|
||||
this._element.style.height = `${height}px`;
|
||||
}
|
||||
if (top !== null) {
|
||||
this._element.style.top = `${top}px`;
|
||||
}
|
||||
if (left !== null) {
|
||||
this._element.style.left = `${left}px`;
|
||||
}
|
||||
if (width !== null) {
|
||||
this._element.style.width = `${width}px`;
|
||||
}
|
||||
this.setBounds({ height, width, top, left });
|
||||
}),
|
||||
{
|
||||
dispose: () => {
|
||||
for (const iframe of iframes) {
|
||||
iframe.style.pointerEvents = 'auto';
|
||||
}
|
||||
},
|
||||
},
|
||||
addDisposableWindowListener(window, 'mouseup', () => {
|
||||
move.dispose();
|
||||
this._onDidChange.fire();
|
||||
this._onDidChangeEnd.fire();
|
||||
})
|
||||
);
|
||||
})
|
||||
|
@ -45,7 +45,7 @@ import { DockviewGroupPanel } from './dockviewGroupPanel';
|
||||
import { DockviewPanelModel } from './dockviewPanelModel';
|
||||
import { getPanelData } from '../dnd/dataTransfer';
|
||||
import { Overlay } from '../dnd/overlay';
|
||||
import { toggleClass } from '../dom';
|
||||
import { toggleClass, watchElementResize } from '../dom';
|
||||
import {
|
||||
DockviewFloatingGroupPanel,
|
||||
IDockviewFloatingGroupPanel,
|
||||
@ -369,8 +369,19 @@ export class DockviewComponent
|
||||
overlay
|
||||
);
|
||||
|
||||
const disposable = watchElementResize(group.element, (entry) => {
|
||||
const { width, height } = entry.contentRect;
|
||||
group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel
|
||||
});
|
||||
|
||||
floatingGroupPanel.addDisposables(
|
||||
overlay.onDidChange(() => {
|
||||
// this is either a resize or a move
|
||||
// to inform the panels .layout(...) the group with it's current size
|
||||
// don't care about resize since the above watcher handles that
|
||||
group.layout(group.height, group.width);
|
||||
}),
|
||||
overlay.onDidChangeEnd(() => {
|
||||
this._bufferOnDidLayoutChange.fire();
|
||||
}),
|
||||
group.onDidChange((event) => {
|
||||
@ -381,6 +392,8 @@ export class DockviewComponent
|
||||
}),
|
||||
{
|
||||
dispose: () => {
|
||||
disposable.dispose();
|
||||
|
||||
group.model.isFloating = false;
|
||||
remove(this.floatingGroups, floatingGroupPanel);
|
||||
this.updateWatermark();
|
||||
@ -451,7 +464,7 @@ export class DockviewComponent
|
||||
if (this.floatingGroups) {
|
||||
for (const floating of this.floatingGroups) {
|
||||
// ensure floting groups stay within visible boundaries
|
||||
floating.overlay.renderWithinBoundaryConditions();
|
||||
floating.overlay.setBounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -621,7 +634,7 @@ export class DockviewComponent
|
||||
}
|
||||
|
||||
for (const floatingGroup of this.floatingGroups) {
|
||||
floatingGroup.overlay.renderWithinBoundaryConditions();
|
||||
floatingGroup.overlay.setBounds();
|
||||
}
|
||||
|
||||
if (typeof activeGroup === 'string') {
|
||||
|
@ -210,7 +210,6 @@ export const DockviewPersistance = (props: { theme?: string }) => {
|
||||
<div
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<DockviewReact
|
||||
|
@ -78,6 +78,7 @@ export const HoistedDockviewPanel = <T extends object>(
|
||||
style={{
|
||||
position: 'absolute',
|
||||
overflow: 'hidden',
|
||||
zIndex: 999,
|
||||
pointerEvents: 'none', // prevent this wrapper contain stealing events
|
||||
}}
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user