@@ -23,8 +23,6 @@ import {
2323
2424import { Signal , ISignal } from '@lumino/signaling' ;
2525
26- import { DashboardIcons } from './icons' ;
27-
2826import { Widgetstore , WidgetPosition } from './widgetstore' ;
2927
3028import { DashboardLayout } from './layout' ;
@@ -152,8 +150,14 @@ export class DashboardWidget extends Widget {
152150 } ) ;
153151 }
154152
155- const resizer = DashboardWidget . createResizer ( ) ;
156- this . node . appendChild ( resizer ) ;
153+ const resizerTopLeft = DashboardWidget . createResizer ( 'top-left' ) ;
154+ const resizerTopRight = DashboardWidget . createResizer ( 'top-right' ) ;
155+ const resizerBottomLeft = DashboardWidget . createResizer ( 'bottom-left' ) ;
156+ const resizerBottomRight = DashboardWidget . createResizer ( 'bottom-right' ) ;
157+ this . node . appendChild ( resizerTopLeft ) ;
158+ this . node . appendChild ( resizerTopRight ) ;
159+ this . node . appendChild ( resizerBottomLeft ) ;
160+ this . node . appendChild ( resizerBottomRight ) ;
157161
158162 this . addClass ( DASHBOARD_WIDGET_CLASS ) ;
159163 this . addClass ( EDITABLE_WIDGET_CLASS ) ;
@@ -294,9 +298,19 @@ export class DashboardWidget extends Widget {
294298
295299 // this.node.style.opacity = '0.6';
296300
301+ const elem = target as HTMLElement ;
297302 // Set mode to resize if the mousedown happened on a resizer.
298- if ( ( target as HTMLElement ) . classList . contains ( 'pr-Resizer' ) ) {
303+ if ( elem . classList . contains ( 'pr-Resizer' ) ) {
299304 this . _mouseMode = 'resize' ;
305+ if ( elem . classList . contains ( 'pr-ResizerTopRight' ) ) {
306+ this . _selectedResizer = 'top-right' ;
307+ } else if ( elem . classList . contains ( 'pr-ResizerTopLeft' ) ) {
308+ this . _selectedResizer = 'top-left' ;
309+ } else if ( elem . classList . contains ( 'pr-ResizerBottomLeft' ) ) {
310+ this . _selectedResizer = 'bottom-left' ;
311+ } else {
312+ this . _selectedResizer = 'bottom-right' ;
313+ }
300314 } else {
301315 this . _mouseMode = 'drag' ;
302316 }
@@ -305,12 +319,16 @@ export class DashboardWidget extends Widget {
305319
306320 const rect = this . node . getBoundingClientRect ( ) ;
307321
322+ const { width, height, top, left } = this . pos ;
323+
308324 this . _clickData = {
309325 pressX : event . clientX ,
310326 pressY : event . clientY ,
311327 cell,
312- pressWidth : parseInt ( this . node . style . width , 10 ) ,
313- pressHeight : parseInt ( this . node . style . height , 10 ) ,
328+ origWidth : width ,
329+ origHeight : height ,
330+ origLeft : left ,
331+ origTop : top ,
314332 target : this . node . cloneNode ( true ) as HTMLElement ,
315333 widgetX : rect . left ,
316334 widgetY : rect . top
@@ -352,16 +370,44 @@ export class DashboardWidget extends Widget {
352370 * Handle `mousemove` events when the widget mouseMode is `resize`.
353371 */
354372 private _resizeMouseMove ( event : MouseEvent ) : void {
355- const { pressX, pressY, pressWidth, pressHeight } = this . _clickData ;
373+ const {
374+ pressX,
375+ pressY,
376+ origWidth,
377+ origHeight,
378+ origLeft,
379+ origTop
380+ } = this . _clickData ;
356381
357382 const deltaX = event . clientX - pressX ;
358383 const deltaY = event . clientY - pressY ;
359384
360- const width = Math . max ( pressWidth + deltaX , DashboardWidget . MIN_WIDTH ) ;
361- const height = Math . max ( pressHeight + deltaY , DashboardWidget . MIN_HEIGHT ) ;
385+ let { width, height, top, left } = this . pos ;
386+
387+ switch ( this . _selectedResizer ) {
388+ case 'bottom-right' :
389+ width = Math . max ( origWidth + deltaX , DashboardWidget . MIN_WIDTH ) ;
390+ height = Math . max ( origHeight + deltaY , DashboardWidget . MIN_HEIGHT ) ;
391+ break ;
392+ case 'bottom-left' :
393+ width = Math . max ( origWidth - deltaX , DashboardWidget . MIN_WIDTH ) ;
394+ height = Math . max ( origHeight + deltaY , DashboardWidget . MIN_HEIGHT ) ;
395+ left = origLeft + deltaX ;
396+ break ;
397+ case 'top-right' :
398+ width = Math . max ( origWidth + deltaX , DashboardWidget . MIN_WIDTH ) ;
399+ height = Math . max ( origHeight - deltaY , DashboardWidget . MIN_HEIGHT ) ;
400+ top = origTop + deltaY ;
401+ break ;
402+ case 'top-left' :
403+ width = Math . max ( origWidth - deltaX , DashboardWidget . MIN_WIDTH ) ;
404+ height = Math . max ( origHeight - deltaY , DashboardWidget . MIN_HEIGHT ) ;
405+ top = origTop + deltaY ;
406+ left = origLeft + deltaX ;
407+ break ;
408+ }
362409
363- this . node . style . width = `${ width } px` ;
364- this . node . style . height = `${ height } px` ;
410+ this . pos = { width, height, top, left } ;
365411
366412 if ( this . mode === 'grid-edit' ) {
367413 ( this . parent . layout as DashboardLayout ) . drawDropZone ( this . pos , '#2b98f0' ) ;
@@ -377,8 +423,12 @@ export class DashboardWidget extends Widget {
377423 fitContent ( ) : void {
378424 const element = this . _content . node ;
379425 // Pixels are added to prevent weird wrapping issues. Kind of a hack.
380- this . node . style . width = `${ element . clientWidth + 3 } px` ;
381- this . node . style . height = `${ element . clientHeight + 2 } px` ;
426+ this . pos = {
427+ width : element . clientWidth + 3 ,
428+ height : element . clientHeight + 2 ,
429+ left : undefined ,
430+ top : undefined
431+ } ;
382432 }
383433
384434 /**
@@ -642,15 +692,18 @@ export class DashboardWidget extends Widget {
642692 private _clickData : {
643693 pressX : number ;
644694 pressY : number ;
645- pressWidth : number ;
646- pressHeight : number ;
695+ origWidth : number ;
696+ origHeight : number ;
697+ origLeft : number ;
698+ origTop : number ;
647699 target : HTMLElement ;
648700 cell : CodeCell | MarkdownCell ;
649701 widgetX : number ;
650702 widgetY : number ;
651703 } | null = null ;
652704 private _locked = false ;
653705 private _content : Widget ;
706+ private _selectedResizer : DashboardWidget . ResizerCorner ;
654707}
655708
656709/**
@@ -710,18 +763,39 @@ export namespace DashboardWidget {
710763 return `DashboardWidget-${ UUID . uuid4 ( ) } ` ;
711764 }
712765
766+ /**
767+ * A type for describing the corner for a widget resizer.
768+ */
769+ export type ResizerCorner =
770+ | 'top-left'
771+ | 'bottom-left'
772+ | 'top-right'
773+ | 'bottom-right' ;
774+
713775 /**
714776 * Create a resizer element for a dashboard widget.
715777 */
716- export function createResizer ( ) : HTMLElement {
778+ export function createResizer ( corner : ResizerCorner ) : HTMLElement {
717779 const resizer = document . createElement ( 'div' ) ;
718780 resizer . classList . add ( 'pr-Resizer' ) ;
719- DashboardIcons . resizer2 . element ( {
720- container : resizer ,
721- width : '15px' ,
722- height : '15px' ,
723- pointerEvents : 'none'
724- } ) ;
781+
782+ switch ( corner ) {
783+ case 'top-left' :
784+ resizer . classList . add ( 'pr-ResizerTopLeft' ) ;
785+ break ;
786+ case 'top-right' :
787+ resizer . classList . add ( 'pr-ResizerTopRight' ) ;
788+ break ;
789+ case 'bottom-left' :
790+ resizer . classList . add ( 'pr-ResizerBottomLeft' ) ;
791+ break ;
792+ case 'bottom-right' :
793+ resizer . classList . add ( 'pr-ResizerBottomRight' ) ;
794+ break ;
795+ default :
796+ resizer . classList . add ( 'pr-ResizerBottomRight' ) ;
797+ break ;
798+ }
725799
726800 return resizer ;
727801 }
0 commit comments