Skip to content

Commit

Permalink
refactor: added fields to widgets.
Browse files Browse the repository at this point in the history
Define properties of widgets as fields.
WIP.

Closes #47
  • Loading branch information
poirierlouis committed Nov 4, 2024
1 parent e030c5a commit 4e43966
Show file tree
Hide file tree
Showing 59 changed files with 978 additions and 415 deletions.
4 changes: 2 additions & 2 deletions src/app/formatters/lua-sol2.formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,8 @@ export class FIGLuaSol2Formatter extends FIGFormatter {
const isInteger: boolean = FIGInputNumberWidget.isInteger(widget.dataType);
let value: string;

if (size === 0) {
const number: number = widget.value as number;
if (size === 1) {
const number: number = widget.value[0];

value = isInteger ? number.toString() : number.toFixed(precision);
} else {
Expand Down
11 changes: 11 additions & 0 deletions src/app/models/fields/array.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Field, FieldType} from "./field";

export class ArrayField extends Field<unknown[]> {
constructor(name: string,
label: string,
value?: unknown[],
isOptional: boolean = false,
defaultValue?: unknown[]) {
super(FieldType.array, name, label, value, isOptional, defaultValue);
}
}
11 changes: 11 additions & 0 deletions src/app/models/fields/bool.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Field, FieldType} from "./field";

export class BoolField extends Field<boolean> {
constructor(name: string,
label: string,
value?: boolean,
isOptional: boolean = false,
defaultValue?: boolean) {
super(FieldType.bool, name, label, value, isOptional, defaultValue);
}
}
12 changes: 12 additions & 0 deletions src/app/models/fields/color.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Field, FieldType} from "./field";
import {Color} from "../math";

export class ColorField extends Field<Color> {
constructor(name: string,
label: string,
value?: Color,
isOptional: boolean = false,
defaultValue?: Color) {
super(FieldType.color, name, label, value, isOptional, defaultValue);
}
}
22 changes: 22 additions & 0 deletions src/app/models/fields/enum.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {Field, FieldType} from "./field";

export type EnumFieldType = string | number;

export interface EnumOption {
readonly value: number;
readonly label: string;
}

export class EnumField<T extends EnumFieldType> extends Field<T> {
public readonly options: EnumOption[];

constructor(name: string,
label: string,
options: EnumOption[],
value?: T,
isOptional: boolean = false,
defaultValue?: T) {
super(FieldType.enum, name, label, value, isOptional, defaultValue);
this.options = options;
}
}
65 changes: 65 additions & 0 deletions src/app/models/fields/field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
export enum FieldType {
bool,
integer,
float,
number,
string,
array,
size,
flags,
color,
enum,
}

export type FieldCallback = (value: unknown) => void;

export class Field<T = unknown> {
readonly type: FieldType;
readonly name: string;
readonly label: string;
readonly isOptional: boolean;

value?: T;
defaultValue?: T;

private readonly listeners: FieldCallback[];

protected constructor(type: FieldType,
name: string,
label: string,
value?: T,
isOptional: boolean = false,
defaultValue?: T) {
this.type = type;
this.name = name;
this.label = label;
this.value = value;
this.isOptional = isOptional;
this.defaultValue = defaultValue;

this.listeners = [];
}

get isRequired(): boolean {
return !this.isOptional;
}

public addListener(fn: FieldCallback): void {
this.listeners.push(fn);
}

public removeListener(fn: FieldCallback): void {
const index: number = this.listeners.findIndex((listener) => listener === fn);

if (index !== -1) {
this.listeners.splice(index, 1);
}
}

public emit(): void {
for (const listener of this.listeners) {
listener(this.value);
}
}

}
11 changes: 11 additions & 0 deletions src/app/models/fields/flags.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Field, FieldType} from "./field";

export class FlagsField extends Field<number> {
constructor(name: string,
label: string,
value?: number,
isOptional: boolean = false,
defaultValue?: number) {
super(FieldType.flags, name, label, value, isOptional, defaultValue);
}
}
11 changes: 11 additions & 0 deletions src/app/models/fields/float.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Field, FieldType} from "./field";

export class FloatField extends Field<number> {
constructor(name: string,
label: string,
value?: number,
isOptional: boolean = false,
defaultValue?: number) {
super(FieldType.float, name, label, value, isOptional, defaultValue);
}
}
11 changes: 11 additions & 0 deletions src/app/models/fields/integer.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Field, FieldType} from "./field";

export class IntegerField extends Field<number> {
constructor(name: string,
label: string,
value?: number,
isOptional: boolean = false,
defaultValue?: number) {
super(FieldType.integer, name, label, value, isOptional, defaultValue);
}
}
11 changes: 11 additions & 0 deletions src/app/models/fields/number.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Field, FieldType} from "./field";

export class NumberField extends Field<number> {
constructor(name: string,
label: string,
value?: number,
isOptional: boolean = false,
defaultValue?: number) {
super(FieldType.number, name, label, value, isOptional, defaultValue);
}
}
12 changes: 12 additions & 0 deletions src/app/models/fields/size.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Field, FieldType} from "./field";
import {Size} from "../math";

export class SizeField extends Field<Size> {
constructor(name: string,
label: string,
value?: Size,
isOptional: boolean = false,
defaultValue?: Size) {
super(FieldType.size, name, label, value, isOptional, defaultValue);
}
}
11 changes: 11 additions & 0 deletions src/app/models/fields/string.field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Field, FieldType} from "./field";

export class StringField extends Field<string> {
constructor(name: string,
label: string,
value?: string,
isOptional: boolean = false,
defaultValue?: string) {
super(FieldType.string, name, label, value, isOptional, defaultValue);
}
}
8 changes: 8 additions & 0 deletions src/app/models/object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function hasFunction(obj: object | null, fnName: string): boolean {
while ((obj = Reflect.getPrototypeOf(obj as object)) !== null) {
if (Reflect.ownKeys(obj).find((key) => key === fnName)) {
return true;
}
}
return false;
}
4 changes: 2 additions & 2 deletions src/app/models/widgets/bloc-for.widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ export class FIGBlocForWidget extends FIGContainer {
{name: 'size', optional: true, default: 10}
];

size: number;
size: number = 10;

constructor(options?: FIGBlocForOptions) {
super(FIGWidgetType.blocFor, true);
this.size = options?.size ?? 10;
this.registerInteger('size', 'Size', options?.size, true, 10);
this._focusOffset.y = 0;
}

Expand Down
27 changes: 18 additions & 9 deletions src/app/models/widgets/button.widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {FIGWidgetType} from "./widget";
import {FIGTooltipOption, FIGWithTooltip} from "./with-tooltip.widget";
import {Vector2} from "../math";
import {FIGSerializeProperty} from "../../parsers/document.parser";
import {EnumOption} from "../fields/enum.field";

export enum FIGDir {
left,
Expand All @@ -11,6 +12,14 @@ export enum FIGDir {
none = -1
}

export const FIGDirOptions: EnumOption[] = [
{value: FIGDir.none, label: 'None'},
{value: FIGDir.left, label: 'Left'},
{value: FIGDir.right, label: 'Right'},
{value: FIGDir.up, label: 'Up'},
{value: FIGDir.down, label: 'Down'},
];

export interface FIGButtonOptions extends FIGTooltipOption {
readonly label?: string;
readonly isFill?: boolean;
Expand All @@ -27,18 +36,18 @@ export class FIGButtonWidget extends FIGWithTooltip {
{name: 'tooltip', optional: true, default: undefined},
];

label: string;
isFill: boolean;
isSmall: boolean;
arrow: FIGDir;
label: string = 'Button';
isFill: boolean = false;
isSmall: boolean = false;
arrow: FIGDir = FIGDir.none;

constructor(options?: FIGButtonOptions) {
super(FIGWidgetType.button, true);
this.label = options?.label ?? 'Button';
this.isFill = options?.isFill ?? false;
this.isSmall = options?.isSmall ?? false;
this.arrow = options?.arrow ?? FIGDir.none;
this.tooltip = options?.tooltip;
this.registerString('label', 'Label', options?.label ?? 'Button');
this.registerString('tooltip', 'Tooltip', options?.tooltip, true);
this.registerBool('isFill', 'Fill', options?.isFill, true, false);
this.registerBool('isSmall', 'Small', options?.isSmall, true, false);
this.registerEnum('arrow', 'Arrow', FIGDirOptions, options?.arrow, true, FIGDir.none);
}

public get name(): string {
Expand Down
10 changes: 5 additions & 5 deletions src/app/models/widgets/checkbox.widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ export class FIGCheckboxWidget extends FIGWithTooltip {
{name: 'tooltip', optional: true, default: undefined},
];

label: string;
isChecked: boolean;
label: string = 'Checkbox';
isChecked: boolean = false;

constructor(options?: FIGCheckboxOptions) {
super(FIGWidgetType.checkbox, true);
this.label = options?.label ?? 'Checkbox';
this.isChecked = options?.isChecked ?? false;
this.tooltip = options?.tooltip;
this.registerString('label', 'Label', options?.label ?? 'Checkbox');
this.registerString('tooltip', 'Tooltip', options?.tooltip, true);
this.registerBool('isChecked', 'Checked', options?.isChecked, true, false);
}

public get name(): string {
Expand Down
16 changes: 8 additions & 8 deletions src/app/models/widgets/child-window.widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ export class FIGChildWindowWidget extends FIGContainer {
{name: 'flags', optional: true, default: 0},
];

label: string;
size: Size;
frameBorder: boolean;
flags: number;
label: string = 'Child Window';
size: Size = {width: 0, height: 0};
frameBorder: boolean = true;
flags: number = 0;

constructor(options?: FIGChildWindowOptions) {
super(FIGWidgetType.childWindow, true);
this.label = options?.label ?? 'Child Window';
this.size = options?.size ?? {width: 0, height: 0};
this.frameBorder = options?.frameBorder ?? true;
this.flags = options?.flags ?? 0;
this.registerString('label', 'Label', options?.label ?? 'Child Window');
this.registerSize('size', 'Size', options?.size ?? {width: 0, height: 0});
this.registerBool('frameBorder', 'Show frame border', options?.frameBorder, true, true);
this.registerFlags('flags', 'Flags', options?.flags, true, 0);
}

public get name(): string {
Expand Down
8 changes: 4 additions & 4 deletions src/app/models/widgets/collapsing-header.widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ export class FIGCollapsingHeaderWidget extends FIGContainer {
{name: 'flags', optional: true, default: 0},
];

label: string;
flags: number;
label: string = 'Header';
flags: number = 0;

constructor(options?: FIGCollapsingHeaderOptions) {
super(FIGWidgetType.collapsingHeader, true);
this.label = options?.label ?? 'Header';
this.flags = options?.flags ?? 0;
this.registerString('label', 'Label', options?.label ?? 'Header');
this.registerFlags('flags', 'Flags', options?.flags, true, 0);
this._focusOffset.x = 0;
}

Expand Down
14 changes: 7 additions & 7 deletions src/app/models/widgets/combo.widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ export class FIGComboWidget extends FIGWithTooltip {
{name: 'tooltip', optional: true, default: undefined}
];

label: string;
readonly items: string[];
label: string = 'Combo';
items: string[] = [];

selectedItem: number;
selectedItem: number = 0;

constructor(options?: FIGComboOptions) {
super(FIGWidgetType.combo, true);
this.label = options?.label ?? 'Combo';
this.items = options?.items ?? [];
this.selectedItem = 0;
this.tooltip = options?.tooltip;
this.registerString('label', 'Label', options?.label ?? 'Combo');
this.registerString('tooltip', 'Tooltip', options?.tooltip, true);
this.registerArray('items', 'List of items', options?.items, true, []);
this.registerInteger('selectedItem', 'Selected item', 0, true, 0);
}

public get name(): string {
Expand Down
10 changes: 5 additions & 5 deletions src/app/models/widgets/dummy.widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ export class FIGDummyWidget extends FIGWithTooltip {
{name: 'tooltip', optional: true, default: undefined}
];

width: number;
height: number;
width: number = 100;
height: number = 100;

constructor(options?: FIGDummyOptions) {
super(FIGWidgetType.dummy, true);
this.width = options?.width ?? 100;
this.height = options?.height ?? 100;
this.tooltip = options?.tooltip;
this.registerString('tooltip', 'Tooltip', options?.tooltip, true);
this.registerInteger('width', 'Width', options?.width, true, 100);
this.registerInteger('height', 'Height', options?.height, true, 100);
}

public readonly name = 'Dummy';
Expand Down
Loading

0 comments on commit 4e43966

Please sign in to comment.