Skip to content

Commit

Permalink
Merge pull request #113 from cameron-toy/design_improvements
Browse files Browse the repository at this point in the history
Design and resizer improvements
  • Loading branch information
cameron-toy authored Feb 9, 2021
2 parents 13a84d1 + 7e713c6 commit 31acb8b
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 79 deletions.
6 changes: 6 additions & 0 deletions src/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import greyDashboardSvgstr from '../style/icons/dashboard_icon_filled_grey.svg';
import blueDashboardSvgstr from '../style/icons/dashboard_icon_filled_blue.svg';
import whiteDashboardOutlineSvgstr from '../style/icons/dashboard_icon_outline_white.svg';
import greyDashboardOutlineSvgstr from '../style/icons/dashboard_icon_outline_grey.svg';
import tealDashboardSvgstr from '../style/icons/dashboard_icon_filled_teal.svg';
import redoIcon from '../style/icons/redo.svg';
import fullscreenIcon from '../style/icons/fullscreen.svg';
import statusIcon from '../style/icons/dummy.svg';
Expand All @@ -17,6 +18,11 @@ import resizer2Svgstr from '../style/icons/drag indicator lines.svg';
* Dashboard icons
*/
export namespace DashboardIcons {
export const tealDashboard = new LabIcon({
name: 'pr-icons:teal-dashboard',
svgstr: tealDashboardSvgstr
});

export const whiteDashboard = new LabIcon({
name: 'pr-icons:white-dashboard',
svgstr: whiteDashboardSvgstr
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const extension: JupyterFrontEndPlugin<IDashboardTracker> = {
contentType: 'file',
extensions: ['.dashboard', '.dash'],
fileFormat: 'text',
icon: DashboardIcons.blueDashboard,
icon: DashboardIcons.tealDashboard,
iconLabel: 'Dashboard',
mimeTypes: ['application/json']
};
Expand Down Expand Up @@ -550,7 +550,7 @@ function addCommands(

commands.addCommand(CommandIDs.createNew, {
label: 'Dashboard',
icon: DashboardIcons.blueDashboard,
icon: DashboardIcons.tealDashboard,
execute: async args => {
// A new file is created and opened separately to override the default
// opening behavior when there's a notebook and open the dashboard in a
Expand Down
8 changes: 4 additions & 4 deletions src/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ export class DashboardLayout extends Layout {
*/
updateLayoutFromWidgetstore(): void {
this._signalChanges = false;
const records = this._widgetstore.getWidgets();
const records = this._widgetstore.get(Widgetstore.WIDGET_SCHEMA);
each(records, record => {
this._updateLayoutFromRecord(record);
});
Expand Down Expand Up @@ -869,10 +869,10 @@ export class DashboardLayout extends Layout {
*/
setTileSize(s: number): void {
this._tileSize = s;
const backgroundPosition = `0 0, 0 ${s}px, ${s}px -${s}px, -${s}px 0px`;
// const backgroundPosition = `0 0, 0 ${s}px, ${s}px -${s}px, -${s}px 0px`;

this.canvas.style.backgroundPosition = backgroundPosition;
this.canvas.style.backgroundSize = `${2 * s}px ${2 * s}px`;
// this.canvas.style.backgroundPosition = backgroundPosition;
this.canvas.style.backgroundSize = `${s}px ${s}px`;
this.parent.update();

this.startBatch();
Expand Down
140 changes: 114 additions & 26 deletions src/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { CodeCell, MarkdownCell } from '@jupyterlab/cells';

import { Widget } from '@lumino/widgets';

import { MessageLoop } from '@lumino/messaging';

import { UUID, MimeData } from '@lumino/coreutils';

import { ArrayExt } from '@lumino/algorithm';
Expand All @@ -23,8 +25,6 @@ import {

import { Signal, ISignal } from '@lumino/signaling';

import { DashboardIcons } from './icons';

import { Widgetstore, WidgetPosition } from './widgetstore';

import { DashboardLayout } from './layout';
Expand Down Expand Up @@ -132,8 +132,20 @@ export class DashboardWidget extends Widget {
this.node.style.opacity = '0';

container.classList.add(DASHBOARD_WIDGET_CHILD_CLASS);
container.appendChild(clone.node);
this.node.appendChild(container);

// Fake an attach in order to render LaTeX properly.
// Note: This is not how you should use Lumino widgets.
if (this.parent) {
if (this.parent!.isAttached) {
MessageLoop.sendMessage(clone, Widget.Msg.BeforeAttach);
container.appendChild(clone.node);
this.node.appendChild(container);
if (this.parent!.isAttached) {
MessageLoop.sendMessage(clone, Widget.Msg.AfterAttach);
}
}
}

this._content = clone;

const done = (): void => {
Expand All @@ -152,8 +164,14 @@ export class DashboardWidget extends Widget {
});
}

const resizer = DashboardWidget.createResizer();
this.node.appendChild(resizer);
const resizerTopLeft = DashboardWidget.createResizer('top-left');
const resizerTopRight = DashboardWidget.createResizer('top-right');
const resizerBottomLeft = DashboardWidget.createResizer('bottom-left');
const resizerBottomRight = DashboardWidget.createResizer('bottom-right');
this.node.appendChild(resizerTopLeft);
this.node.appendChild(resizerTopRight);
this.node.appendChild(resizerBottomLeft);
this.node.appendChild(resizerBottomRight);

this.addClass(DASHBOARD_WIDGET_CLASS);
this.addClass(EDITABLE_WIDGET_CLASS);
Expand Down Expand Up @@ -294,9 +312,19 @@ export class DashboardWidget extends Widget {

// this.node.style.opacity = '0.6';

const elem = target as HTMLElement;
// Set mode to resize if the mousedown happened on a resizer.
if ((target as HTMLElement).classList.contains('pr-Resizer')) {
if (elem.classList.contains('pr-Resizer')) {
this._mouseMode = 'resize';
if (elem.classList.contains('pr-ResizerTopRight')) {
this._selectedResizer = 'top-right';
} else if (elem.classList.contains('pr-ResizerTopLeft')) {
this._selectedResizer = 'top-left';
} else if (elem.classList.contains('pr-ResizerBottomLeft')) {
this._selectedResizer = 'bottom-left';
} else {
this._selectedResizer = 'bottom-right';
}
} else {
this._mouseMode = 'drag';
}
Expand All @@ -305,12 +333,16 @@ export class DashboardWidget extends Widget {

const rect = this.node.getBoundingClientRect();

const { width, height, top, left } = this.pos;

this._clickData = {
pressX: event.clientX,
pressY: event.clientY,
cell,
pressWidth: parseInt(this.node.style.width, 10),
pressHeight: parseInt(this.node.style.height, 10),
origWidth: width,
origHeight: height,
origLeft: left,
origTop: top,
target: this.node.cloneNode(true) as HTMLElement,
widgetX: rect.left,
widgetY: rect.top
Expand Down Expand Up @@ -352,16 +384,44 @@ export class DashboardWidget extends Widget {
* Handle `mousemove` events when the widget mouseMode is `resize`.
*/
private _resizeMouseMove(event: MouseEvent): void {
const { pressX, pressY, pressWidth, pressHeight } = this._clickData;
const {
pressX,
pressY,
origWidth,
origHeight,
origLeft,
origTop
} = this._clickData;

const deltaX = event.clientX - pressX;
const deltaY = event.clientY - pressY;

const width = Math.max(pressWidth + deltaX, DashboardWidget.MIN_WIDTH);
const height = Math.max(pressHeight + deltaY, DashboardWidget.MIN_HEIGHT);
let { width, height, top, left } = this.pos;

switch (this._selectedResizer) {
case 'bottom-right':
width = Math.max(origWidth + deltaX, DashboardWidget.MIN_WIDTH);
height = Math.max(origHeight + deltaY, DashboardWidget.MIN_HEIGHT);
break;
case 'bottom-left':
width = Math.max(origWidth - deltaX, DashboardWidget.MIN_WIDTH);
height = Math.max(origHeight + deltaY, DashboardWidget.MIN_HEIGHT);
left = origLeft + deltaX;
break;
case 'top-right':
width = Math.max(origWidth + deltaX, DashboardWidget.MIN_WIDTH);
height = Math.max(origHeight - deltaY, DashboardWidget.MIN_HEIGHT);
top = origTop + deltaY;
break;
case 'top-left':
width = Math.max(origWidth - deltaX, DashboardWidget.MIN_WIDTH);
height = Math.max(origHeight - deltaY, DashboardWidget.MIN_HEIGHT);
top = origTop + deltaY;
left = origLeft + deltaX;
break;
}

this.node.style.width = `${width}px`;
this.node.style.height = `${height}px`;
this.pos = { width, height, top, left };

if (this.mode === 'grid-edit') {
(this.parent.layout as DashboardLayout).drawDropZone(this.pos, '#2b98f0');
Expand All @@ -375,10 +435,14 @@ export class DashboardWidget extends Widget {
* Fit widget width/height to the width/height of the underlying content.
*/
fitContent(): void {
const element = this._content.node;
const element = this._content.node.firstChild as HTMLElement;
// Pixels are added to prevent weird wrapping issues. Kind of a hack.
this.node.style.width = `${element.clientWidth + 3}px`;
this.node.style.height = `${element.clientHeight + 2}px`;
this.pos = {
width: element.clientWidth + 3,
height: element.clientHeight + 2,
left: undefined,
top: undefined
};
}

/**
Expand Down Expand Up @@ -642,15 +706,18 @@ export class DashboardWidget extends Widget {
private _clickData: {
pressX: number;
pressY: number;
pressWidth: number;
pressHeight: number;
origWidth: number;
origHeight: number;
origLeft: number;
origTop: number;
target: HTMLElement;
cell: CodeCell | MarkdownCell;
widgetX: number;
widgetY: number;
} | null = null;
private _locked = false;
private _content: Widget;
private _selectedResizer: DashboardWidget.ResizerCorner;
}

/**
Expand Down Expand Up @@ -710,18 +777,39 @@ export namespace DashboardWidget {
return `DashboardWidget-${UUID.uuid4()}`;
}

/**
* A type for describing the corner for a widget resizer.
*/
export type ResizerCorner =
| 'top-left'
| 'bottom-left'
| 'top-right'
| 'bottom-right';

/**
* Create a resizer element for a dashboard widget.
*/
export function createResizer(): HTMLElement {
export function createResizer(corner: ResizerCorner): HTMLElement {
const resizer = document.createElement('div');
resizer.classList.add('pr-Resizer');
DashboardIcons.resizer2.element({
container: resizer,
width: '15px',
height: '15px',
pointerEvents: 'none'
});

switch (corner) {
case 'top-left':
resizer.classList.add('pr-ResizerTopLeft');
break;
case 'top-right':
resizer.classList.add('pr-ResizerTopRight');
break;
case 'bottom-left':
resizer.classList.add('pr-ResizerBottomLeft');
break;
case 'bottom-right':
resizer.classList.add('pr-ResizerBottomRight');
break;
default:
resizer.classList.add('pr-ResizerBottomRight');
break;
}

return resizer;
}
Expand Down
Loading

0 comments on commit 31acb8b

Please sign in to comment.