Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/mathuo/dockview into master
Browse files Browse the repository at this point in the history
  • Loading branch information
mathuo committed Oct 25, 2021
2 parents ecbf0f7 + 0f85c09 commit cfb1b5c
Show file tree
Hide file tree
Showing 17 changed files with 245 additions and 78 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"packages": [
"packages/*"
],
"version": "0.0.25",
"version": "0.0.26",
"command": {
"publish": {
"message": "chore(release): publish %s"
Expand Down
2 changes: 1 addition & 1 deletion packages/dockview-demo/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/dockview-demo/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dockview-demo",
"private": true,
"version": "0.0.25",
"version": "0.0.26",
"description": "Demo project for https://github.com/mathuo/dockview",
"scripts": {
"build": "npm run build-webpack && npm run build-storybook",
Expand All @@ -14,7 +14,7 @@
"author": "https://github.com/mathuo",
"license": "MIT",
"dependencies": {
"dockview": "^0.0.25",
"dockview": "^0.0.26",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"recoil": "^0.4.1"
Expand Down
135 changes: 135 additions & 0 deletions packages/dockview-demo/src/services/sidebarItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { ViewContainer } from './viewContainer';
import * as React from 'react';
import { toggleClass } from '../dom';

export const Container = (props: {
container: ViewContainer;
isActive: boolean;
onDragOver: (e: React.DragEvent) => void;
onDrop: (e: React.DragEvent, direction: 'top' | 'bottom') => void;
onClick: (e: React.MouseEvent) => void;
}) => {
const ref = React.useRef<HTMLDivElement>(null);
const [selection, setSelection] = React.useState<
'top' | 'bottom' | undefined
>(undefined);
const isDragging = React.useRef<boolean>(false);

const [dragEntered, setDragEntered] = React.useState<boolean>(false);

const onDragOver = (e: React.DragEvent) => {
if (isDragging.current) {
return;
}

setDragEntered(true);

e.preventDefault();

const target = e.target as HTMLDivElement;

const width = target.clientWidth;
const height = target.clientHeight;

if (width === 0 || height === 0) {
return; // avoid div!0
}

const x = e.nativeEvent.offsetX;
const y = e.nativeEvent.offsetY;
const xp = (100 * x) / width;
const yp = (100 * y) / height;

const isTop = yp < 50;
const isBottom = yp >= 50;

setSelection(isTop ? 'top' : 'bottom');

props.onDragOver(e);
};

const onDragLeave = (e: React.DragEvent) => {
if (isDragging.current) {
return;
}

setDragEntered(false);

setSelection(undefined);
};

const onDrop = (e: React.DragEvent) => {
if (isDragging.current) {
return;
}

setDragEntered(false);

props.onDrop(e, selection);

setSelection(undefined);
};

const onDragEnter = (e: React.DragEvent) => {
e.preventDefault();
};

const onDragStart = (e: React.DragEvent) => {
isDragging.current = true;

e.dataTransfer.setData(
'application/json',
JSON.stringify({ container: props.container.id })
);
};

const onDragEnd = (e: React.DragEvent) => {
isDragging.current = false;

setDragEntered(false);
};

return (
<div
ref={ref}
draggable={true}
onClick={props.onClick}
onDragOver={onDragOver}
onDragEnter={onDragEnter}
onDragStart={onDragStart}
onDragLeave={onDragLeave}
onDragEnd={onDragEnd}
onDrop={onDrop}
style={{
borderLeft: props.isActive
? '1px solid white'
: '1px solid transparent',
}}
className="container-item"
>
{dragEntered && (
<div
style={{
position: 'absolute',
top: '0px',
left: '0px',
height: '100%',
width: '100%',
backgroundColor: 'transparent',
boxSizing: 'border-box',
borderTop: selection === 'top' ? '2px solid white' : '',
borderBottom:
selection === 'bottom' ? '2px solid white' : '',
pointerEvents: 'none',
}}
/>
)}
<span
style={{ fontSize: '30px' }}
className="material-icons-outlined"
>
{props.container.icon}
</span>
</div>
);
};
2 changes: 1 addition & 1 deletion packages/dockview-demo/src/services/viewContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class PaneviewContainer implements ViewContainer<SerializedPaneview> {
}

get views() {
return this._views;
return [...this._views];
}

get schema(): SerializedPaneview | undefined {
Expand Down
18 changes: 18 additions & 0 deletions packages/dockview-demo/src/services/viewService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface IViewService extends IDisposable {
targetLocation: number
): void;
insertContainerAfter(source: ViewContainer, target: ViewContainer): void;
insertContainerBefore(source: ViewContainer, target: ViewContainer): void;
addViews(view: View, viewContainer: ViewContainer, location?: number): void;
removeViews(removeViews: View[], viewContainer: ViewContainer): void;
getViewContainer(id: string): ViewContainer | undefined;
Expand Down Expand Up @@ -103,6 +104,23 @@ export class ViewService implements IViewService {
this._onDidContainersChange.fire();
}

insertContainerBefore(source: ViewContainer, target: ViewContainer): void {
const sourceIndex = this._viewContainers.findIndex(
(c) => c.id === source.id
);

const view = this._viewContainers.splice(sourceIndex, 1)[0];

const targetIndex = this._viewContainers.findIndex(
(c) => c.id === target.id
);

this._viewContainers.splice(Math.max(targetIndex, 0), 0, view);
this._viewContainers = [...this._viewContainers];

this._onDidContainersChange.fire();
}

addContainer(container: ViewContainer): void {
this._viewContainers = [...this._viewContainers, container];
this._activeViewContainerId = container.id;
Expand Down
9 changes: 9 additions & 0 deletions packages/dockview-demo/src/services/widgets.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@
background-color: green !important;
}
}

.container-item {
display: flex;
justify-content: center;
align-items: center;
height: 48px;
box-sizing: border-box;
position: relative;
}
111 changes: 61 additions & 50 deletions packages/dockview-demo/src/services/widgets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { IViewService, ViewService } from './viewService';
import { DefaultView } from './view';
import { RegisteredView, VIEW_REGISTRY } from './viewRegistry';
import { toggleClass } from '../dom';
import { Container } from './sidebarItem';
import './widgets.scss';

class ViewServiceModel {
Expand Down Expand Up @@ -172,18 +173,30 @@ export const Activitybar = (props: IGridviewPanelProps) => {
};

const onContainerDrop = (targetContainer: ViewContainer) => (
event: React.DragEvent
event: React.DragEvent,
direction: 'top' | 'bottom'
) => {
const data = event.dataTransfer.getData('application/json');
if (data) {
const { container } = JSON.parse(data);
const sourceContainer = viewService.model.getViewContainer(
container
);
viewService.model.insertContainerAfter(
sourceContainer,
targetContainer
);

switch (direction) {
case 'bottom':
viewService.model.insertContainerAfter(
sourceContainer,
targetContainer
);
break;
case 'top':
viewService.model.insertContainerBefore(
sourceContainer,
targetContainer
);
break;
}
}
};

Expand All @@ -204,48 +217,31 @@ export const Activitybar = (props: IGridviewPanelProps) => {
}
};

const onDragOver = (container: ViewContainer) => (e: React.DragEvent) => {
const api = registry.get<GridviewApi>('gridview');

const sidebarPanel = api.getPanel('sidebar');
if (!sidebarPanel.api.isVisible) {
api.setVisible(sidebarPanel, true);
sidebarPanel.focus();
}

viewService.model.setActiveViewContainer(container.id);
};

return (
<div style={{ background: 'rgb(51,51,51)', cursor: 'pointer' }}>
{containers.map((container, i) => {
const isActive = activeContainerid === container.id;
return (
<div
<Container
key={i}
container={container}
isActive={isActive}
onDragOver={onDragOver(container)}
onClick={onClick(container)}
onDragOver={(e) => {
e.preventDefault();
onClick(container, true)(e);
}}
onDragEnter={(e) => {
e.preventDefault();
}}
draggable={true}
onDragStart={(e) => {
e.dataTransfer.setData(
'application/json',
JSON.stringify({ container: container.id })
);
}}
onDrop={onContainerDrop(container)}
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '48px',
boxSizing: 'border-box',
borderLeft: isActive
? '1px solid white'
: '1px solid transparent',
}}
key={i}
>
{/* {container.id} */}
<span
style={{ fontSize: '30px' }}
className="material-icons-outlined"
>
{container.icon}
</span>
</div>
/>
);
})}
<ExtraSpace onNewContainer={onNewContainer} />
Expand Down Expand Up @@ -360,25 +356,40 @@ export const SidebarPart = (props: { id: string }) => {
};

const onDidDrop = (event: PaneviewDropEvent) => {
const data = event.event.getData();
const data = event.getData();

const containerData = event.event.dataTransfer.getData(
'application/json'
);

if (containerData) {
const { container } = JSON.parse(containerData);

const sourceContainer = viewService.model.getViewContainer(
container
);
const targetContainer = viewService.model.getViewContainer(
props.id
);

sourceContainer.views.forEach((v) => {
viewService.model.moveViewToLocation(v, targetContainer, 0);
});

return;
}

if (!data) {
return;
}

const targetPanel = event.event.panel;
const targetPanel = event.panel;
const allPanels = event.api.getPanels();
let toIndex = allPanels.indexOf(targetPanel);

// if (
// event.event.position === Position.Left ||
// event.event.position === Position.Top
// ) {
// toIndex = Math.max(0, toIndex - 1);
// }
if (
event.event.position === Position.Right ||
event.event.position === Position.Bottom
event.position === Position.Right ||
event.position === Position.Bottom
) {
toIndex = Math.min(allPanels.length, toIndex + 1);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/dockview/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit cfb1b5c

Please sign in to comment.