Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(react-components): Generalize settings popup #4684

Merged
merged 11 commits into from
Jul 29, 2024
17 changes: 15 additions & 2 deletions react-components/src/architecture/base/commands/BaseCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ export abstract class BaseCommand {
// CONSTRUCTOR
// ==================================================

constructor() {
public constructor() {
BaseCommand._counter++;
this._uniqueId = BaseCommand._counter;
}

// ==================================================
// VIRTUAL METHODS (To be override)
// VIRTUAL METHODS (To be overridden)
// =================================================

public get name(): string {
Expand Down Expand Up @@ -79,6 +79,15 @@ export abstract class BaseCommand {
return this.isEnabled;
}

/**
* Gets a value indicating whether the command can be toggled on or off.
* Override this property if the command can be toggled.
* You must also override isChecked to get the toggle state.
*/
public get isToggle(): boolean {
return false;
}

public get isChecked(): boolean {
return false;
}
Expand Down Expand Up @@ -137,6 +146,10 @@ export abstract class BaseCommand {
}
}

// ==================================================
// INSTANCE METHODS: Others
// ==================================================

public getLabel(translate: TranslateDelegate): string {
const { key, fallback } = this.tooltip;
if (key === undefined) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,53 @@
*/

import { type RevealRenderTarget } from '../renderTarget/RevealRenderTarget';
import { BaseCommand } from './BaseCommand';
import { type BaseCommand } from './BaseCommand';
import { RenderTargetCommand } from './RenderTargetCommand';

/**
* Base class for all command and tools. These are object that can do a
* user interaction with the system. It also have enough information to
* generate the UI for the command.
* Base class for all option like commands. Override createOptions to add options
* or use add method to add them in.
*/

export abstract class BaseOptionCommand extends BaseCommand {
export abstract class BaseOptionCommand extends RenderTargetCommand {
private _options: BaseCommand[] | undefined = undefined;

// ==================================================
// OVERRIDES
// ==================================================

public override attach(renderTarget: RevealRenderTarget): void {
this._renderTarget = renderTarget;
for (const option of this.options) {
if (option instanceof RenderTargetCommand) {
option.attach(renderTarget);
}
}
}
// ==================================================
// VIRTUAL METHODS
// ==================================================

public createOptions(): BaseCommand[] {
return []; // Override this to add options
protected createOptions(): BaseCommand[] {
return []; // Override this to add options or use the add method
}

// ==================================================
// INSTANCE METHODS
// ==================================================

public getOrCreateOptions(renderTarget: RevealRenderTarget): BaseCommand[] {
public get options(): BaseCommand[] {
if (this._options === undefined) {
this._options = this.createOptions();
for (const option of this._options) {
if (option instanceof RenderTargetCommand) {
option.attach(renderTarget);
}
}
}
return this._options;
}

public get selectedOption(): BaseCommand | undefined {
if (this._options === undefined) {
return undefined;
}
return this._options.find((option) => option.isChecked);
return this.options.find((option) => option.isChecked);
}

public add(command: BaseCommand): void {
this.options.push(command);
nilscognite marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*!
* Copyright 2024 Cognite AS
*/

import { RenderTargetCommand } from './RenderTargetCommand';

export abstract class BaseSliderCommand extends RenderTargetCommand {
// ==================================================
// INSTANCE FIELDS
// =================================================

readonly min: number;
readonly max: number;
readonly step: number;

// ==================================================
// CONSTRUCTOR
// ==================================================

protected constructor(min: number, max: number, step: number) {
super();
this.min = min;
this.max = max;
this.step = step;
}

// ==================================================
// VIRTUAL METHODS (To be overridden)
// =================================================

public abstract get value(): number;

public abstract set value(value: number);
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ export abstract class RenderTargetCommand extends BaseCommand {
return activeTool.undoManager;
}

// ==================================================
// INSTANCE METHODS
// ==================================================

public attach(renderTarget: RevealRenderTarget): void {
this._renderTarget = renderTarget;
}

// ==================================================
// INSTANCE METHODS
// ==================================================

public addTransaction(transaction: Transaction | undefined): void {
if (transaction === undefined) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export abstract class ShowAllDomainObjectsCommand extends InstanceCommand {
return 'EyeShow';
}

public override get isToggle(): boolean {
return true;
}

public override get isChecked(): boolean {
return this.isAnyVisible();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export abstract class ShowDomainObjectsOnTopCommand extends InstanceCommand {
return 'Flag';
}

public override get isToggle(): boolean {
return true;
}

public override get isChecked(): boolean {
return !this.getDepthTest();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,36 @@
* Copyright 2024 Cognite AS
*/

import { type BaseCommand } from '../commands/BaseCommand';
import { BaseOptionCommand } from '../commands/BaseOptionCommand';
import { RenderTargetCommand } from '../commands/RenderTargetCommand';
import { type TranslateKey } from '../utilities/TranslateKey';

const KEYBOARD_SPEED_VALUES = [0.5, 1, 2, 5, 10, 20];
const DEFAULT_OPTIONS = [0.5, 1, 2, 5, 10, 20];

export class KeyboardSpeedCommand extends BaseOptionCommand {
// ==================================================
// OVERRIDES
// CONSTRUCTOR
// ==================================================

public override get tooltip(): TranslateKey {
return { key: 'FLY_SPEED', fallback: 'Set fly speed on the camera' };
constructor(supportedTypes = DEFAULT_OPTIONS) {
super();
for (const value of supportedTypes) {
this.add(new OptionCommand(value));
}
}

public override createOptions(): BaseCommand[] {
const options: BaseCommand[] = [];
for (const value of KEYBOARD_SPEED_VALUES) {
options.push(new OptionCommand(value));
}
return options;
// ==================================================
// OVERRIDES
// ==================================================

public override get tooltip(): TranslateKey {
return { key: 'FLY_SPEED', fallback: 'Set camera fly speed' };
}
}

// Note: This is not exported, as it is only used internally
class OptionCommand extends RenderTargetCommand {
private readonly _value;
private readonly _value: number;

public constructor(value: number) {
super();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*!
* Copyright 2024 Cognite AS
*/

import { PointColorType } from '@cognite/reveal';
import { BaseOptionCommand } from '../commands/BaseOptionCommand';
import { RenderTargetCommand } from '../commands/RenderTargetCommand';
import { type TranslateKey } from '../utilities/TranslateKey';

const DEFAULT_OPTIONS: PointColorType[] = [
PointColorType.Rgb,
PointColorType.Classification,
PointColorType.Depth,
PointColorType.Height,
PointColorType.Intensity
];

export class SetPointColorTypeCommand extends BaseOptionCommand {
// ==================================================
// CONSTRUCTOR
// ==================================================

constructor(supportedTypes = DEFAULT_OPTIONS) {
super();
for (const value of supportedTypes) {
this.add(new OptionCommand(value));
}
}

// ==================================================
// OVERRIDES
// ==================================================

public override get tooltip(): TranslateKey {
return { key: 'POINT_COLOR', fallback: 'Point color' };
}

public override get isEnabled(): boolean {
return this.renderTarget.getPointClouds().next().value !== undefined;
nilscognite marked this conversation as resolved.
Show resolved Hide resolved
}
}

// Note: This is not exported, as it is only used internally

class OptionCommand extends RenderTargetCommand {
private readonly _value: PointColorType;

public constructor(value: PointColorType) {
super();
this._value = value;
}

public override get tooltip(): TranslateKey {
return getTranslateKey(this._value);
}

public override get isChecked(): boolean {
// Let the first PointCloud decide the color type
const pointCloud = this.renderTarget.getPointClouds().next().value;
if (pointCloud === undefined) {
return false;
}
return pointCloud.pointColorType === this._value;
}

public override invokeCore(): boolean {
for (const pointCloud of this.renderTarget.getPointClouds()) {
pointCloud.pointColorType = this._value;
}
return true;
}
}

// ==================================================
// PRIVATE FUNCTIONS
// ==================================================

function getTranslateKey(type: PointColorType): TranslateKey {
switch (type) {
case PointColorType.Rgb:
return { key: 'RGB', fallback: 'RGB' };
case PointColorType.Depth:
return { key: 'DEPTH', fallback: 'Depth' };
case PointColorType.Height:
return { key: 'HEIGHT', fallback: 'Height' };
case PointColorType.Classification:
return { key: 'CLASSIFICATION', fallback: 'Classification' };
case PointColorType.Intensity:
return { key: 'INTENSITY', fallback: 'Intensity' };
case PointColorType.LevelOfDetail:
return { key: 'LEVEL_OF_DETAIL', fallback: 'LevelOfDetail' };
case PointColorType.PointIndex:
return { key: 'POINT_INDEX', fallback: 'PointIndex' };
default:
return { key: 'UNKNOWN', fallback: 'Unknown' };
}
}
Loading
Loading