Skip to content

Commit

Permalink
wip: fullscreen panels
Browse files Browse the repository at this point in the history
  • Loading branch information
mathuo committed Dec 9, 2023
1 parent b17aa24 commit 0fa2e4f
Show file tree
Hide file tree
Showing 14 changed files with 350 additions and 48 deletions.
75 changes: 75 additions & 0 deletions packages/dockview-core/src/__tests__/gridview/a.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<div class="branch-node">
<div class="split-view-container horizontal separator-border">
<div class="sash-container">
<div class="sash d isabled" style="left: 0px; top: 0px"></div>
</div>
<div class="view-container">
<div class="view" style="width: 0px; left: 0px">
<div class="mock-grid-view leaf-node" id="1"></div>
</div>
<div class="view visible" style="width: 1000px; left: 0px">
<div class="branch-node">
<div class="split-view-container vertical separator-border">
<div class="sash-container">
<div
class="sash disabled"
style="left: 0px; top: 0px"
></div>
</div>
<div class="view-container">
<div class="view" style="height: 0px; top: 0px">
<div class="mock-grid-view leaf-node" id="3">
< /div>
</div>
<div
class="view visible"
style="height: 1000px; top: 0px"
>
<div class="branch-node">
<div
class="split-view-container horizont al separator-border"
>
<div class="sash-container">
<div
class="sash disabled"
style="left: 0px; top: 0px"
></div>
</div>
<div class="view-con tainer">
<div
class="view"
style="
width: 0px;
left: 0px;
"
>
<div
class="mock-grid-view leaf-node"
id="4"
></div>
</div>
<div
class="view visibl e"
style="
width: 1000px;
left: 0px;
"
>
<div
class="mock-grid-view leaf-node"
id="2"
></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
< /div>
</div>
</div>
</div>
</div>
</div>
12 changes: 12 additions & 0 deletions packages/dockview-core/src/api/component.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -804,4 +804,16 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
moveToPrevious(options?: MovementOptions): void {
this.component.moveToPrevious(options);
}

maximizeGroup(panel: IDockviewPanel): void {
this.component.maximizeGroup(panel.group);
}

hasMaximizedGroup(): boolean {
return this.component.hasMaximizedGroup();
}

exitMaxmizedGroup(): void {
this.component.exitMaximizedGroup();
}
}
5 changes: 5 additions & 0 deletions packages/dockview-core/src/api/dockviewPanelApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface DockviewPanelApi
position?: Position;
index?: number;
}): void;
maximize(): void;
}

export class DockviewPanelApiImpl
Expand Down Expand Up @@ -120,4 +121,8 @@ export class DockviewPanelApiImpl
close(): void {
this.group.model.closePanel(this.panel);
}

maximize(): void {
this.accessor.maximizeGroup(this.panel.group);
}
}
29 changes: 29 additions & 0 deletions packages/dockview-core/src/dockview/dockviewComponent.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,35 @@
width: 100%;
z-index: 1;
}

.dv-fullscreen {
z-index: 9;
transition: all 0.25s ease-in-out;
// outline: 1px solid red;
position: absolute;
}

.dv-fullscreen-animate {
top: 0px !important;
left: 0px !important;
width: 100% !important;
height: 100% !important;
}

.dv-fullscreen-close-button {
position: absolute;
bottom: 0px;
right: 0px;
z-index: 999;
width: 20px;
height: 20px;
color: white;
background-color: black;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
}

.groupview {
Expand Down
9 changes: 7 additions & 2 deletions packages/dockview-core/src/dockview/dockviewComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
import { directionToPosition, Droptarget, Position } from '../dnd/droptarget';
import { tail, sequenceEquals, remove } from '../array';
import { DockviewPanel, IDockviewPanel } from './dockviewPanel';
import { CompositeDisposable } from '../lifecycle';
import { CompositeDisposable, IDisposable } from '../lifecycle';
import { Event, Emitter } from '../events';
import { Watermark } from './components/watermark/watermark';
import {
Expand Down Expand Up @@ -46,7 +46,11 @@ import { DockviewPanelModel } from './dockviewPanelModel';
import { getPanelData } from '../dnd/dataTransfer';
import { Parameters } from '../panel/types';
import { Overlay } from '../dnd/overlay';
import { toggleClass, watchElementResize } from '../dom';
import {
FocusTrap as FocusRetainment,
toggleClass,
watchElementResize,
} from '../dom';
import {
DockviewFloatingGroupPanel,
IDockviewFloatingGroupPanel,
Expand All @@ -55,6 +59,7 @@ import {
GroupDragEvent,
TabDragEvent,
} from './components/titlebar/tabsContainer';
import { createCloseButton } from '../svg';

const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;

Expand Down
4 changes: 2 additions & 2 deletions packages/dockview-core/src/dockview/dockviewGroupPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export class DockviewGroupPanel
id,
'groupview_default',
{
minimumHeight: 100,
minimumWidth: 100,
minimumHeight: 0,
minimumWidth: 0,
},
new DockviewGroupPanelApiImpl(id, accessor)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ export interface IDockviewGroupPanelModel extends IPanel {
): boolean;
}

export type DockviewGroupMode = 'grid' | 'floating' | 'fullscreen' | 'popout';

export class DockviewGroupPanelModel
extends CompositeDisposable
implements IDockviewGroupPanelModel
Expand Down
21 changes: 21 additions & 0 deletions packages/dockview-core/src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,24 @@ export function quasiPreventDefault(event: Event): void {
export function quasiDefaultPrevented(event: Event): boolean {
return (event as any)[QUASI_PREVENT_DEFAULT_KEY];
}

export class FocusTrap {
private element: Element | null;

constructor() {
this.element = null;
}

retain(): void {
this.element = document.activeElement;
}

focus(): void {
if (
document.activeElement !== this.element &&
this.element?.parentElement
) {
(this.element as HTMLElement)?.focus?.();
}
}
}
15 changes: 15 additions & 0 deletions packages/dockview-core/src/gridview/baseComponentGridview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ export interface IBaseGrid<T extends IGridPanelView> {
layout(width: number, height: number, force?: boolean): void;
setVisible(panel: T, visible: boolean): void;
isVisible(panel: T): boolean;
maximizeGroup(panel: T): void;
exitMaximizedGroup(): void;
hasMaximizedGroup(): boolean;
}

export abstract class BaseGrid<T extends IGridPanelView>
Expand Down Expand Up @@ -174,6 +177,18 @@ export abstract class BaseGrid<T extends IGridPanelView>
return this.gridview.isViewVisible(getGridLocation(panel.element));
}

maximizeGroup(panel: T): void {
this.gridview.maximizeView(panel);
}

exitMaximizedGroup(): void {
this.gridview.exitMaximizedView();
}

hasMaximizedGroup(): boolean {
return this.gridview.hasMaximizedView();
}

protected doAddGroup(
group: T,
location: number[] = [0],
Expand Down
60 changes: 48 additions & 12 deletions packages/dockview-core/src/gridview/branchNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export class BranchNode extends CompositeDisposable implements IView {
readonly onDidChange: Event<{ size?: number; orthogonalSize?: number }> =
this._onDidChange.event;

private readonly _onDidVisibilityChange = new Emitter<boolean>();
readonly onDidVisibilityChange: Event<boolean> =
this._onDidVisibilityChange.event;

get width(): number {
return this.orientation === Orientation.HORIZONTAL
? this.size
Expand All @@ -48,11 +52,23 @@ export class BranchNode extends CompositeDisposable implements IView {
get minimumSize(): number {
return this.children.length === 0
? 0
: Math.max(...this.children.map((c) => c.minimumOrthogonalSize));
: Math.max(
...this.children.map((c, index) =>
this.splitview.isViewVisible(index)
? c.minimumOrthogonalSize
: 0
)
);
}

get maximumSize(): number {
return Math.min(...this.children.map((c) => c.maximumOrthogonalSize));
return Math.min(
...this.children.map((c, index) =>
this.splitview.isViewVisible(index)
? c.maximumOrthogonalSize
: Number.POSITIVE_INFINITY
)
);
}

get minimumOrthogonalSize(): number {
Expand Down Expand Up @@ -163,6 +179,7 @@ export class BranchNode extends CompositeDisposable implements IView {

this.addDisposables(
this._onDidChange,
this._onDidVisibilityChange,
this.splitview.onDidSashEnd(() => {
this._onDidChange.fire({});
})
Expand All @@ -185,7 +202,7 @@ export class BranchNode extends CompositeDisposable implements IView {
return this.splitview.isViewVisible(index);
}

setChildVisible(index: number, visible: boolean): void {
setChildVisible(index: number, visible: boolean): void {
if (index < 0 || index >= this.children.length) {
throw new Error('Invalid index');
}
Expand All @@ -194,7 +211,18 @@ export class BranchNode extends CompositeDisposable implements IView {
return;
}

const wereAllChildrenHidden = this.splitview.contentSize === 0;
this.splitview.setViewVisible(index, visible);
const areAllChildrenHidden = this.splitview.contentSize === 0;

// If all children are hidden then the parent should hide the entire splitview
// If the entire splitview is hidden then the parent should show the splitview when a child is shown
if (
(visible && wereAllChildrenHidden) ||
(!visible && areAllChildrenHidden)
) {
this._onDidVisibilityChange.fire(visible);
}
}

moveChild(from: number, to: number): void {
Expand Down Expand Up @@ -285,15 +313,23 @@ export class BranchNode extends CompositeDisposable implements IView {
private setupChildrenEvents(): void {
this._childrenDisposable.dispose();

this._childrenDisposable = Event.any(
...this.children.map((c) => c.onDidChange)
)((e) => {
/**
* indicate a change has occured to allows any re-rendering but don't bubble
* event because that was specific to this branch
*/
this._onDidChange.fire({ size: e.orthogonalSize });
});
this._childrenDisposable = new CompositeDisposable(
Event.any(...this.children.map((c) => c.onDidChange))((e) => {
/**
* indicate a change has occured to allows any re-rendering but don't bubble
* event because that was specific to this branch
*/
this._onDidChange.fire({ size: e.orthogonalSize });
}),
...this.children.map((c, i) => {
if (c instanceof BranchNode) {
return c.onDidVisibilityChange((visible) => {
this.setChildVisible(i, visible);
});
}
return Disposable.NONE;
})
);
}

public dispose(): void {
Expand Down
Loading

0 comments on commit 0fa2e4f

Please sign in to comment.