feat: additional group api

This commit is contained in:
mathuo 2022-04-27 22:32:21 +01:00
parent 083ca6a8fb
commit fe3d0b23bd
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
8 changed files with 113 additions and 52 deletions

View File

@ -26,7 +26,9 @@ function isBooleanValue(
return typeof canDisplayOverlay === 'boolean';
}
export type CanDisplayOverlay = boolean | ((dragEvent: DragEvent) => boolean);
export type CanDisplayOverlay =
| boolean
| ((dragEvent: DragEvent, state: Quadrant | null) => boolean);
export class Droptarget extends CompositeDisposable {
private target: HTMLElement | undefined;
@ -62,11 +64,29 @@ export class Droptarget extends CompositeDisposable {
new DragAndDropObserver(this.element, {
onDragEnter: () => undefined,
onDragOver: (e) => {
const width = this.element.clientWidth;
const height = this.element.clientHeight;
if (width === 0 || height === 0) {
return; // avoid div!0
}
const x = e.offsetX;
const y = e.offsetY;
const xp = (100 * x) / width;
const yp = (100 * y) / height;
const quadrant = this.calculateQuadrant(
this.options.validOverlays,
xp,
yp
);
if (isBooleanValue(this.options.canDisplayOverlay)) {
if (!this.options.canDisplayOverlay) {
return;
}
} else if (!this.options.canDisplayOverlay(e)) {
} else if (!this.options.canDisplayOverlay(e, quadrant)) {
return;
}
@ -90,24 +110,6 @@ export class Droptarget extends CompositeDisposable {
return;
}
const width = this.target.clientWidth;
const height = this.target.clientHeight;
if (width === 0 || height === 0) {
return; // avoid div!0
}
const x = e.offsetX;
const y = e.offsetY;
const xp = (100 * x) / width;
const yp = (100 * y) / height;
const quadrant = this.calculateQuadrant(
this.options.validOverlays,
xp,
yp
);
const isSmallX = width < 100;
const isSmallY = height < 100;

View File

@ -4,6 +4,7 @@ import {
IViewDeserializer,
} from '../gridview/gridview';
import { GroupviewPanelState, IGroupPanel } from '../groupview/groupPanel';
import { GroupPanelViewState } from '../groupview/groupview';
import { DockviewComponent } from './dockviewComponent';
export interface IPanelDeserializer {
@ -18,9 +19,10 @@ export class DefaultDeserializer implements IViewDeserializer {
}
) {}
public fromJSON(node: ISerializedLeafNode): IGridView {
const children = node.data.views;
const active = node.data.activeView;
public fromJSON(node: ISerializedLeafNode<GroupPanelViewState>): IGridView {
const data = node.data;
const children = data.views;
const active = data.activeView;
const panels: IGroupPanel[] = [];
@ -33,7 +35,18 @@ export class DefaultDeserializer implements IViewDeserializer {
return this.layout.createGroup({
panels,
activePanel: panels.find((p) => p.id === active),
id: node.data.id,
id: data.id,
locked: !!data.locked,
headerHidden: !!data.headerHidden,
});
}
}
/**
* isGroup
*
*
* panel.group.locked = true
* panel.group.header.hiddden = true
*
*/

View File

@ -188,7 +188,7 @@ export class DockviewComponent
set tabHeight(height: number | undefined) {
this.options.tabHeight = height;
this._groups.forEach((value) => {
value.value.model.tabHeight = height;
value.value.model.header.height = height;
});
}
@ -704,7 +704,7 @@ export class DockviewComponent
view.initialize();
if (typeof this.options.tabHeight === 'number') {
view.model.tabHeight = this.options.tabHeight;
view.model.header.height = this.options.tabHeight;
}
return view;

View File

@ -169,7 +169,7 @@ export class DockviewGroupPanel
// the obtain the correct dimensions of the content panel we must deduct the tab height
this.api._onDidPanelDimensionChange.fire({
width,
height: height - (this.group?.model.tabHeight || 0),
height: height - (this.group?.model.header.height || 0),
});
this.view?.layout(width, height);

View File

@ -241,9 +241,9 @@ const serializeBranchNode = <T extends IGridView>(
};
};
export interface ISerializedLeafNode {
export interface ISerializedLeafNode<T = any> {
type: 'leaf';
data: any;
data: T;
size: number;
visible?: boolean;
}

View File

@ -48,36 +48,47 @@ interface GroupMoveEvent {
index?: number;
}
export interface GroupOptions {
interface CoreGroupOptions {
locked?: boolean;
headerHidden?: boolean;
}
export interface GroupOptions extends CoreGroupOptions {
readonly panels?: IGroupPanel[];
readonly activePanel?: IGroupPanel;
readonly id?: string;
tabHeight?: number;
}
export interface GroupviewChangeEvent {
readonly kind: GroupChangeKind2;
readonly panel?: IGroupPanel;
}
export interface GroupPanelViewState {
export interface GroupPanelViewState extends CoreGroupOptions {
views: string[];
activeView?: string;
id: string;
}
export interface GroupviewChangeEvent {
readonly kind: GroupChangeKind2;
readonly panel?: IGroupPanel;
}
export interface GroupviewDropEvent {
nativeEvent: DragEvent;
position: Position;
index?: number;
}
export interface IHeader {
hidden: boolean;
height: number | undefined;
}
export interface IGroupview extends IDisposable, IGridPanelView {
readonly isActive: boolean;
readonly size: number;
readonly panels: IGroupPanel[];
readonly tabHeight: number | undefined;
readonly activePanel: IGroupPanel | undefined;
locked: boolean;
readonly header: IHeader;
readonly onDidDrop: Event<GroupviewDropEvent>;
// state
isPanelActive: (panel: IGroupPanel) => boolean;
@ -111,6 +122,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
private _activePanel?: IGroupPanel;
private watermark?: IWatermarkRenderer;
private _isGroupActive = false;
private _locked = false;
private mostRecentlyUsed: IGroupPanel[] = [];
@ -141,13 +153,12 @@ export class Groupview extends CompositeDisposable implements IGroupview {
return this._activePanel;
}
get tabHeight(): number | undefined {
return this.tabsContainer.height;
get locked(): boolean {
return this._locked;
}
set tabHeight(height: number | undefined) {
this.tabsContainer.height = height;
this.layout(this._width, this._height);
set locked(value: boolean) {
this._locked = value;
}
get isActive(): boolean {
@ -188,6 +199,10 @@ export class Groupview extends CompositeDisposable implements IGroupview {
);
}
get header(): IHeader {
return this.tabsContainer;
}
constructor(
private readonly container: HTMLElement,
private accessor: IDockviewComponent,
@ -210,9 +225,14 @@ export class Groupview extends CompositeDisposable implements IGroupview {
tabHeight: options.tabHeight,
});
this.contentContainer = new ContentContainer();
this.dropTarget = new Droptarget(this.contentContainer.element, {
validOverlays: 'all',
canDisplayOverlay: (event) => {
canDisplayOverlay: (event, quadrant) => {
if (this.locked && !quadrant) {
return false;
}
const data = getPanelData();
if (data) {
@ -231,6 +251,9 @@ export class Groupview extends CompositeDisposable implements IGroupview {
this.contentContainer.element
);
this.header.hidden = !!options.headerHidden;
this.locked = !!options.locked;
this.addDisposables(
this._onMove,
this._onDidGroupChange,
@ -281,11 +304,21 @@ export class Groupview extends CompositeDisposable implements IGroupview {
}
public toJSON(): GroupPanelViewState {
return {
const result: GroupPanelViewState = {
views: this.tabsContainer.panels,
activeView: this._activePanel?.id,
id: this.id,
};
if (this.locked) {
result.locked = true;
}
if (this.header.hidden) {
result.headerHidden = true;
}
return result;
}
public moveToNext(options?: {

View File

@ -1,17 +1,17 @@
import { IFrameworkPart } from '../panel/types';
import { IDockviewComponent } from '../dockview/dockviewComponent';
import { GridviewPanelApiImpl } from '../api/gridviewPanelApi';
import { Groupview, GroupOptions } from './groupview';
import { Groupview, GroupOptions, IGroupview } from './groupview';
import { GridviewPanel, IGridviewPanel } from '../gridview/gridviewPanel';
export interface IGroupviewPanel extends IGridviewPanel {
model: Groupview;
model: IGroupview;
}
export class GroupviewPanel extends GridviewPanel implements IGroupviewPanel {
private readonly _model: Groupview;
get model(): Groupview {
get model(): IGroupview {
return this._model;
}
@ -42,7 +42,7 @@ export class GroupviewPanel extends GridviewPanel implements IGroupviewPanel {
}
initialize() {
this.model.initialize();
this._model.initialize();
}
setActive(isActive: boolean): void {

View File

@ -33,6 +33,7 @@ export interface ITabsContainer extends IDisposable {
closePanel: (panel: IGroupPanel) => void;
openPanel: (panel: IGroupPanel, index?: number) => void;
setActionElement(element: HTMLElement | undefined): void;
hidden: boolean;
show(): void;
hide(): void;
}
@ -55,6 +56,7 @@ export class TabsContainer
private actions: HTMLElement | undefined;
private _height: number | undefined;
private _hidden = false;
private readonly _onDrop = new Emitter<TabDropIndexEvent>();
readonly onDrop: Event<TabDropIndexEvent> = this._onDrop.event;
@ -85,12 +87,23 @@ export class TabsContainer
}
}
show() {
this.element.style.display = '';
get hidden(): boolean {
return this._hidden;
}
hide() {
this.element.style.display = 'none';
set hidden(value: boolean) {
this._hidden = value;
this.element.style.display = value ? 'none' : '';
}
show(): void {
if (!this.hidden) {
this.element.style.display = '';
}
}
hide(): void {
this._element.style.display = 'none';
}
setActionElement(element: HTMLElement | undefined): void {