Skip to content
Open

22 #30

Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions demo/src/app/components/demo-component/demo.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export class DemoComponent implements OnInit {
private activeButton: 'RESET' | 'RUN' = 'RUN';

ngOnInit(): void {
// apply this setting globally in the demo, so child components behave relatively to their parent component.
// disable on an individual basis by setting the item's applyMatrix property to `true`
paper.settings.applyMatrix = false;
this.project = new paper.Project(this.canvas.nativeElement);
this.backgroundColor = DEFAULT_BACKGROUND_COLOR;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DEFAULT_SCROLLBAR_THICKNESS } from '../../../../../src/constants/dimens

@Component({
selector: 'misc-scrollbar-horizontal-demo',
template: `
template: `
<demo label="Horizontal Scrollbar" height="162"
description="Scrollbar UI component for horizontal scrolling with the default scrollbar and scroll track."
runnable="true" (run)="run()" (reset)="reset()"></demo>
Expand All @@ -23,10 +23,8 @@ export class MiscScrollbarHorizontalDemoComponent implements AfterViewInit {
// sets up Paper Project
const proj = this.demo.getProject();
proj.activate();
proj.activeLayer.applyMatrix = false;
this.demo.backgroundColor = CANVAS_BACKGROUND_COLOR;
const view = paper.view;
const canvas = paper.view.element;
const VIEW_PADDING = 30;

// create content
Expand Down Expand Up @@ -56,21 +54,13 @@ export class MiscScrollbarHorizontalDemoComponent implements AfterViewInit {
// create scrollbar
const scrollbar = new ScrollbarComponent({
content: content,
container: view.element,
containerBounds: view.bounds,
contentOffsetEnd: VIEW_PADDING
},
new paper.Point(VIEW_PADDING, view.size.height - DEFAULT_SCROLLBAR_THICKNESS - 10),
view.bounds.width - VIEW_PADDING * 2
);
if (scrollbar.isEnabled) {
canvas.onmouseenter = scrollbar.containerMouseEnter;
canvas.onmouseleave = scrollbar.containerMouseLeave;

// add scroll listening. paper doesn't have a wheel event handler
canvas.onwheel = (event: WheelEvent) => {
scrollbar.onScroll(event);
};
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ export class MiscScrollbarVerticalDemoComponent implements AfterViewInit {
// sets up Paper Project
const proj = this.demo.getProject();
proj.activate();
proj.activeLayer.applyMatrix = false;
this.demo.backgroundColor = CANVAS_BACKGROUND_COLOR;
const view = paper.view;
const canvas = paper.view.element;
const VIEW_PADDING = 30;

// create content
Expand Down Expand Up @@ -55,22 +53,14 @@ export class MiscScrollbarVerticalDemoComponent implements AfterViewInit {
// create scrollbar
const scrollbar = new ScrollbarComponent({
content: content,
container: view.element,
containerBounds: view.bounds,
contentOffsetEnd: VIEW_PADDING
},
new paper.Point(view.bounds.right - VIEW_PADDING, VIEW_PADDING),
view.bounds.height - VIEW_PADDING * 2,
'vertical'
);
if (scrollbar.isEnabled) {
canvas.onmouseenter = scrollbar.containerMouseEnter;
canvas.onmouseleave = scrollbar.containerMouseLeave;

// add scroll listening. paper doesn't have a wheel event handler
canvas.onwheel = (event: WheelEvent) => {
scrollbar.onScroll(event);
};
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AfterViewInit, Component, ViewChild } from '@angular/core';
import * as paper from 'paper';
import { DemoComponent } from '../demo-component/demo.component';
import { VappData, VappComponent } from '../../../../../src/components/vapp';
import { placeholderArrayOfVappData } from '../../constants/vapp-basic-placeholder-data';
import { placeholderArrayOfVappData } from '../../constants/vapp-static-placeholder-data';
import { ScrollbarComponent } from '../../../../../src/components/scrollbar';
import { CANVAS_BACKGROUND_COLOR } from '../../../../../src/constants/colors';
import { CONNECTOR_RADIUS, DEFAULT_SCROLLBAR_THICKNESS } from '../../../../../src/constants/dimensions';
Expand All @@ -22,63 +22,36 @@ export class VappStaticDemoComponent implements AfterViewInit {
// sets up Paper Project
const proj = this.demo.getProject();
proj.activate();
const view = paper.view;
const canvas = paper.view.element;
const view = proj.view;
this.demo.backgroundColor = CANVAS_BACKGROUND_COLOR;

const VIEW_PADDING = 30;
const DEMO_VAPP_TOP_ALIGNMENT = 59;
const VERTICAL_POSITION = VIEW_PADDING + DEMO_VAPP_TOP_ALIGNMENT + CONNECTOR_RADIUS;
const vapps: Array<VappData> = placeholderArrayOfVappData;

const content = new paper.Group({ applyMatrix: false });
// create origin paper Item for vapps to base position from
const origin = new paper.Path.Circle({
position: new paper.Point(VIEW_PADDING, VERTICAL_POSITION),
radius: 0,
parent: content
});
const content = new paper.Group();

// create vapps
vapps.forEach(vappData => {
const position = new paper.Point(content.lastChild.bounds.right, VERTICAL_POSITION);
const position = new paper.Point(
content.lastChild ? content.lastChild.bounds.right : VIEW_PADDING, VERTICAL_POSITION);
content.addChild(new VappComponent(vappData, position));
});
(content.lastChild as VappComponent).margin.right = 0;

// create view horizontal scrollbar
const horizontalScrollbar = new ScrollbarComponent({
content: content,
container: view.element,
containerBounds: view.bounds,
contentOffsetEnd: VIEW_PADDING
},
new paper.Point(VIEW_PADDING, view.size.height - DEFAULT_SCROLLBAR_THICKNESS - 10),
view.bounds.width - VIEW_PADDING * 2,
'horizontal'
);
if (horizontalScrollbar.isEnabled) {
canvas.onmouseenter = horizontalScrollbar.containerMouseEnter;
canvas.onmouseleave = horizontalScrollbar.containerMouseLeave;
}

// add scroll listening. paper doesn't have a wheel event handler
canvas.onwheel = (event: WheelEvent) => {
// horizontal scrolling sent to horizontal scrollbar
if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
horizontalScrollbar.onScroll(event);
} else {
// vertical scrolling sent to any scrollable vapp that's active/hovered
content.children.forEach(item => {
if (item instanceof VappComponent && item.isScrollable) {
item.setScrollListening(event);
}
});
}
};

// TODO: keydown 'left' and 'right' should always go to horizontalScrollbar. keydown 'up' and 'down' to should go to
// any scrollable vapp that's active/hovered. can try handling with a paper tools service and/or tool stack
ScrollbarComponent.defaultScrollbar = horizontalScrollbar;

// TODO: make sure 'Roboto' font loading finishes before canvas elements are rendered
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { VappData } from '../../../../src/components/vapp';
import { OperatingSystem } from 'iland-sdk';

/**
* Placeholder vApp data for the Vapp Static Demo
Expand All @@ -23,6 +24,7 @@ import { VappData } from '../../../../src/components/vapp';
// 16. variations for unattached vnics
// 17. nat-routed vApp network with no attached vms and vnics
// 18. vapp with no vapp networks or vms
// 19. network-less vm in a list that has other vapp networks
export const placeholderArrayOfVappData: Array<VappData> = [
// 0. nat-routed vapp network
{
Expand Down Expand Up @@ -279,13 +281,13 @@ export const placeholderArrayOfVappData: Array<VappData> = [
vnics: [
{
vnic_id: 0,
network_name: 'A',
is_connected: true
network_name: '',
is_connected: false
},
{
vnic_id: 1,
network_name: '',
is_connected: false
network_name: 'A',
is_connected: true
},
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testing a case for when connected and disconnected vnics are out of order

{
vnic_id: 2,
Expand Down Expand Up @@ -2060,5 +2062,84 @@ export const placeholderArrayOfVappData: Array<VappData> = [
name: 'Coke RES & BURST',
vapp_networks: [],
vms: []
},
// 19. network-less vm in a list that has other vapp networks
{
uuid: '',
name: 'BC Test vApp',
vapp_networks: [
{
uuid: '0',
name: 'A',
vapp_uuid: '',
fence_mode: 'BRIDGED'
},
{
uuid: '1',
name: 'B',
vapp_uuid: '',
fence_mode: 'BRIDGED'
},
{
uuid: '2',
name: 'C',
vapp_uuid: '',
fence_mode: 'BRIDGED'
}
],
vms: [
{
uuid: '',
name: 'redhat-as-01',
vapp_uuid: '',
operatingSystem: 'redhatGuest',
vnics: [
{
vnic_id: 0,
network_name: 'A',
is_connected: true
}
]
},
{
uuid: '',
name: 'debian-as-02',
vapp_uuid: '',
operatingSystem: 'debian8Guest',
vnics: [
{
vnic_id: 0,
network_name: 'B',
is_connected: true
}
]
},
{
uuid: '',
name: 'linux-as-03',
vapp_uuid: '',
operatingSystem: 'other24xLinux64Guest',
vnics: [
{
vnic_id: 1,
network_name: 'C',
is_connected: true
}
]
},
{
uuid: '',
name: 'arch-as-04',
vapp_uuid: '',
operatingSystem: 'btwIUseArch' as OperatingSystem,
vnics: [
{
vnic_id: 0,
network_name: '',
is_connected: false
}
]
}
]
}
];
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { SmallConnectorComponent } from './small-connector';
import { BulletPointConnectionIconComponent } from './bullet-point-connection-icon';
import * as paper from 'paper';

describe('small connector component', () => {
describe('bullet point connection icon component', () => {

beforeAll(() => {
const canvasEl = document.createElement('canvas');
paper.setup(canvasEl);
paper.settings.applyMatrix = false;
});

test('basic properties', () => {
const position = new paper.Point(0, 0);
const connector = new SmallConnectorComponent();
const connector = new BulletPointConnectionIconComponent();
expect(connector.position.x).toBe(position.x);
expect(connector.position.y).toBe(position.y);
});

test('custom position', () => {
const position = new paper.Point(42, -10);
const connector = new SmallConnectorComponent(position);
const connector = new BulletPointConnectionIconComponent(position);
expect(connector.position.x).toBe(position.x);
expect(connector.position.y).toBe(position.y);
});
Expand Down
36 changes: 36 additions & 0 deletions src/components/bullet-point-connection-icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as paper from 'paper';
import { LIGHT_GREY } from '../constants/colors';
import { SMALL_CONNECTOR_SIZE } from '../constants/dimensions';

/**
* Bullet Point Connection Icon Visual Component.
* The small (7px) grey filled circle icon that represents special types of connections or bullet points for labels.
* Used for isolated vApp Network labels or at the end of vApp networks that have no attached VNICs.
*/
export class BulletPointConnectionIconComponent extends paper.Group {

// the small filled circle icon
readonly _icon: paper.Path.Circle;

/**
* Creates a new BulletPointConnectionIconComponent instance.
*
* @param _point the location that the bullet connection icon should be rendered at
*/
constructor(private _point: paper.Point = new paper.Point(0, 0)) {
super();
this.position = _point;
this.pivot = new paper.Point(0, 0);

this._icon = new paper.Path.Circle({
position: new paper.Point(0, 0),
radius: SMALL_CONNECTOR_SIZE / 2,
fillColor: LIGHT_GREY,
parent: this
});
}

get icon(): paper.Path.Circle {
return this._icon;
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
import { ConnectorComponent } from './connector';
import { ConnectionIconComponent } from './connection-icon';
import { VAPP_BACKGROUND_COLOR, CANVAS_BACKGROUND_COLOR } from '../constants/colors';
import * as paper from 'paper';

describe('connector component', () => {
describe('connection icon component', () => {

beforeAll(() => {
const canvasEl = document.createElement('canvas');
paper.setup(canvasEl);
paper.settings.applyMatrix = false;
});

test('basic properties', () => {
const position = new paper.Point(0, 0);
const defaultColor = new paper.Color(VAPP_BACKGROUND_COLOR);
const connector = new ConnectorComponent();
const connector = new ConnectionIconComponent();
expect(connector.position.x).toBe(position.x);
expect(connector.position.y).toBe(position.y);
expect((connector.connector.fillColor as paper.Color).equals(defaultColor)).toBe(true);
expect((connector.icon.fillColor as paper.Color).equals(defaultColor)).toBe(true);
});

test('custom position and fill color', () => {
const position = new paper.Point(-20, 30);
const color = new paper.Color(CANVAS_BACKGROUND_COLOR);
const connector = new ConnectorComponent(position, color);
const connector = new ConnectionIconComponent(position, color);
expect(connector.position.x).toBe(position.x);
expect(connector.position.y).toBe(position.y);
expect((connector.connector.fillColor as paper.Color).equals(color)).toBe(true);
expect((connector.icon.fillColor as paper.Color).equals(color)).toBe(true);
});

});
Loading