custom layout

plugins_custom_layout
Laurent Cozic 2020-12-02 17:26:35 +00:00
parent 717b8da1f8
commit f37bd462a2
3 changed files with 97 additions and 2 deletions

View File

@ -1,6 +1,6 @@
import { LayoutItem, LayoutItemDirection } from './types';
import validateLayout from './validateLayout';
import { canMove, MoveDirection, moveHorizontal, moveVertical } from './movements';
import { canMove, ItemSide, MoveDirection, moveHorizontal, moveItemNear, moveVertical } from './movements';
import findItemByKey from './findItemByKey';
describe('movements', () => {
@ -225,4 +225,37 @@ describe('movements', () => {
expect(layout.children[1].width).toBe(undefined);
});
test('should move an item near another one', () => {
let layout: LayoutItem = validateLayout({
key: 'root',
width: 200,
height: 100,
direction: LayoutItemDirection.Row,
children: [
{
key: 'col1',
resizableRight: true,
direction: LayoutItemDirection.Column,
children: [
{ key: 'item1' },
{ key: 'item2' },
],
},
{
key: 'col2',
},
],
});
// If parent is a ROW and putting item on top of sibling - first move to
// the left, then move right so that item goes inside new container
layout = moveItemNear(layout, 'item1', 'col2', ItemSide.Top);
console.info(layout);
// expect(layout.children[0].width).toBe(20);
// expect(layout.children[1].width).toBe(undefined);
});
});

View File

@ -3,6 +3,8 @@ import { LayoutItem, LayoutItemDirection, tempContainerPrefix } from './types';
import produce from 'immer';
import uuid from '@joplin/lib/uuid';
import validateLayout from './validateLayout';
import findItemByKey from './findItemByKey';
import removeItem from './removeItem';
export enum MoveDirection {
Up = 'up',
@ -11,6 +13,13 @@ export enum MoveDirection {
Right = 'right',
}
export enum ItemSide {
Top = 'top',
Bottom = 'bottom',
Left = 'left',
Right = 'right',
}
enum MovementDirection {
Horizontal = 1,
Vertical = 2,
@ -188,3 +197,42 @@ export function move(layout: LayoutItem, key: string, direction: MoveDirection):
if (direction === MoveDirection.Right) return moveHorizontal(layout, key, +1);
throw new Error('Unreachable');
}
export function moveItemNear(layout:LayoutItem, itemKey:string, nearItemKey:string, side: ItemSide): LayoutItem {
const itemToInsert = findItemByKey(layout, itemKey);
const layoutWithoutItem = removeItem(layout, itemKey);
let moveDirection:MoveDirection = null;
const sideToDirectionMap = {
[ItemSide.Top]: MoveDirection.Up,
[ItemSide.Bottom]: MoveDirection.Down,
[ItemSide.Left]: MoveDirection.Left,
[ItemSide.Right]: MoveDirection.Right,
};
const layoutWithInsertedItem = produce(layoutWithoutItem, (draft: any) => {
iterateItems(draft, (itemIndex: number, item: LayoutItem, parent: LayoutItem) => {
if (item.key !== nearItemKey) return true;
parent.children.splice(itemIndex, 0, itemToInsert);
if (
parent.direction === LayoutItemDirection.Column && side === ItemSide.Top ||
parent.direction === LayoutItemDirection.Row && side === ItemSide.Left
) {
// Nothing to do - already in position
} else {
moveDirection = sideToDirectionMap[side];
}
return false;
});
});
console.info(JSON.stringify(layoutWithInsertedItem, null, 4));
console.info('MOVE', moveDirection);
const updatedLayout = moveDirection ? move(layoutWithInsertedItem, itemKey, moveDirection) : layoutWithInsertedItem;
return validateLayout(updatedLayout);
}

View File

@ -3,6 +3,20 @@ import createViewHandle from '../utils/createViewHandle';
import WebviewController, { ContainerType } from '../WebviewController';
import { ViewHandle } from './types';
interface InitialPosition {
nextTo: string,
}
// initialPosition: {
// nextTo: 'editor',
// side: '',top, right, bottom , left
// size: 100,
// }
interface CreateOptions {
initialPosition: InitialPosition,
}
/**
* Allows creating and managing view panels. View panels currently are
* displayed at the right of the sidebar and allows displaying any HTML
@ -29,7 +43,7 @@ export default class JoplinViewsPanels {
/**
* Creates a new panel
*/
async create(id: string): Promise<ViewHandle> {
async create(id: string, options:CreateOptions = null): Promise<ViewHandle> {
if (!id) {
this.plugin.deprecationNotice('1.5', 'Creating a view without an ID is deprecated. To fix it, change your call to `joplin.views.panels.create("my-unique-id")`');
id = `${this.plugin.viewCount}`;