From 024709a61760e033158c4d461dcc7e385f27bd1c Mon Sep 17 00:00:00 2001 From: rhenck <richard.henck@iqb.hu-berlin.de> Date: Thu, 2 Dec 2021 18:53:17 +0100 Subject: [PATCH] Add Frame element Basically a div with border properties as usual. --- projects/common/id.service.ts | 1 + projects/common/models/uI-element.ts | 2 +- projects/common/shared.module.ts | 4 +- .../common/ui-elements/frame/frame-element.ts | 29 ++++++++++++++ .../ui-elements/frame/frame.component.ts | 23 +++++++++++ projects/common/util/element.factory.ts | 7 ++++ .../ui-element-toolbox.component.html | 5 +++ .../element-model-properties.component.html | 38 +++++++++++++++++++ 8 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 projects/common/ui-elements/frame/frame-element.ts create mode 100644 projects/common/ui-elements/frame/frame.component.ts diff --git a/projects/common/id.service.ts b/projects/common/id.service.ts index 8acc04e0e..e45dca5a6 100644 --- a/projects/common/id.service.ts +++ b/projects/common/id.service.ts @@ -21,6 +21,7 @@ export class IdService { 'radio-group-images': 0, 'drop-list': 0, cloze: 0, + frame: 0, value: 0 }; diff --git a/projects/common/models/uI-element.ts b/projects/common/models/uI-element.ts index 0ddd0d2a4..66ba3718a 100644 --- a/projects/common/models/uI-element.ts +++ b/projects/common/models/uI-element.ts @@ -3,7 +3,7 @@ import { IdService } from '../id.service'; export type UIElementType = 'text' | 'button' | 'text-field' | 'text-area' | 'checkbox' | 'dropdown' | 'radio' | 'image' | 'audio' | 'video' | 'likert' | 'likert_row' | 'radio-group-images' -| 'drop-list' | 'cloze' | 'spell-correct' | 'slider'; +| 'drop-list' | 'cloze' | 'spell-correct' | 'slider' | 'frame'; export type InputElementValue = string[] | string | number | boolean | DragNDropValueObject[] | null; export type DragNDropValueObject = { id: string; diff --git a/projects/common/shared.module.ts b/projects/common/shared.module.ts index cbd0a0661..199ea52de 100644 --- a/projects/common/shared.module.ts +++ b/projects/common/shared.module.ts @@ -46,6 +46,7 @@ import { TextFieldSimpleComponent } from './ui-elements/textfield-simple/text-fi import { SliderComponent } from './ui-elements/slider/slider.component'; import { SpellCorrectComponent } from './ui-elements/spell-correct/spell-correct.component'; import { DropListSimpleComponent } from './ui-elements/drop-list-simple/drop-list-simple.component'; +import { FrameComponent } from './ui-elements/frame/frame.component'; @NgModule({ imports: [ @@ -93,7 +94,8 @@ import { DropListSimpleComponent } from './ui-elements/drop-list-simple/drop-lis DropListSimpleComponent, SliderComponent, SpellCorrectComponent, - TextFieldSimpleComponent + TextFieldSimpleComponent, + FrameComponent ], exports: [ CommonModule, diff --git a/projects/common/ui-elements/frame/frame-element.ts b/projects/common/ui-elements/frame/frame-element.ts new file mode 100644 index 000000000..8c1efb115 --- /dev/null +++ b/projects/common/ui-elements/frame/frame-element.ts @@ -0,0 +1,29 @@ +import { + UIElement, + PositionedElement, + SurfaceElement, + SurfaceProperties, + PositionProperties +} from '../../models/uI-element'; +import { initPositionedElement, initSurfaceElement } from '../../util/unit-interface-initializer'; + +export class FrameElement extends UIElement implements PositionedElement, SurfaceElement { + borderWidth: number = 1; + borderColor: string = 'black'; + borderStyle: 'hidden' | 'solid' | 'dotted' | 'dashed' | 'double' | 'groove' | 'ridge' | 'inset' | 'outset' = 'solid'; + borderRadius: number = 0; + + positionProps: PositionProperties; + surfaceProps: SurfaceProperties; + + constructor(serializedElement: UIElement) { + super(serializedElement); + Object.assign(this, serializedElement); + this.positionProps = initPositionedElement(serializedElement); + this.surfaceProps = initSurfaceElement(serializedElement); + + this.surfaceProps.backgroundColor = + serializedElement.surfaceProps?.backgroundColor as string || + 'transparent'; + } +} diff --git a/projects/common/ui-elements/frame/frame.component.ts b/projects/common/ui-elements/frame/frame.component.ts new file mode 100644 index 000000000..dde15dea6 --- /dev/null +++ b/projects/common/ui-elements/frame/frame.component.ts @@ -0,0 +1,23 @@ +import { Component, Input } from '@angular/core'; +import { FrameElement } from './frame-element'; + +@Component({ + selector: 'app-frame', + template: ` + <div [style.width]="elementModel.borderStyle !== 'hidden' ? + 'calc(100% - ' + (elementModel.borderWidth * 2) + 'px)' : + '100%'" + [style.height]="elementModel.borderStyle !== 'hidden' ? + 'calc(100% - ' + (elementModel.borderWidth * 2) + 'px)' : + '100%'" + [style.border-style]="elementModel.borderStyle" + [style.border-width.px]="elementModel.borderStyle !== 'hidden' ? elementModel.borderWidth : ''" + [style.border-color]="elementModel.borderColor" + [style.border-radius.px]="elementModel.borderRadius" + [style.background-color]="elementModel.surfaceProps.backgroundColor"> + </div> + ` +}) +export class FrameComponent { + @Input() elementModel!: FrameElement; +} diff --git a/projects/common/util/element.factory.ts b/projects/common/util/element.factory.ts index deddd7dcd..4ad43d1b0 100644 --- a/projects/common/util/element.factory.ts +++ b/projects/common/util/element.factory.ts @@ -32,6 +32,8 @@ import { SliderElement } from '../ui-elements/slider/slider-element'; import { SpellCorrectElement } from '../ui-elements/spell-correct/spell-correct-element'; import { SliderComponent } from '../ui-elements/slider/slider.component'; import { SpellCorrectComponent } from '../ui-elements/spell-correct/spell-correct.component'; +import { FrameComponent } from '../ui-elements/frame/frame.component'; +import { FrameElement } from '../ui-elements/frame/frame-element'; export function createElement(elementModel: UIElement): UIElement { let newElement: UIElement; @@ -84,6 +86,9 @@ export function createElement(elementModel: UIElement): UIElement { case 'spell-correct': newElement = new SpellCorrectElement(elementModel); break; + case 'frame': + newElement = new FrameElement(elementModel); + break; default: throw new Error(`ElementType ${elementModel.type} not found!`); } @@ -128,6 +133,8 @@ export function getComponentFactory( return componentFactoryResolver.resolveComponentFactory(SliderComponent); case 'spell-correct': return componentFactoryResolver.resolveComponentFactory(SpellCorrectComponent); + case 'frame': + return componentFactoryResolver.resolveComponentFactory(FrameComponent); default: throw new Error('unknown element'); } diff --git a/projects/editor/src/app/components/unit-view/page-view/new-ui-element-panel/ui-element-toolbox.component.html b/projects/editor/src/app/components/unit-view/page-view/new-ui-element-panel/ui-element-toolbox.component.html index 5b5deeb3f..2ff12016b 100644 --- a/projects/editor/src/app/components/unit-view/page-view/new-ui-element-panel/ui-element-toolbox.component.html +++ b/projects/editor/src/app/components/unit-view/page-view/new-ui-element-panel/ui-element-toolbox.component.html @@ -14,6 +14,11 @@ <mat-icon>smart_button</mat-icon> Knopf </button> + <button mat-raised-button (click)="addUIElement('frame')" + draggable="true" (dragstart)="$event.dataTransfer?.setData('elementType','frame')"> + <mat-icon>crop_square</mat-icon> + Rahmen + </button> <button mat-raised-button (click)="addUIElement('text-field')" draggable="true" (dragstart)="$event.dataTransfer?.setData('elementType','text-field')"> <mat-icon>text_fields</mat-icon> diff --git a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.html b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.html index d3a5fc8a4..4c23420e5 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.html +++ b/projects/editor/src/app/components/unit-view/page-view/properties-panel/element-model-properties.component.html @@ -539,4 +539,42 @@ <input matInput type="number" [value]="combinedProperties.firstColumnSizeRatio" (input)="updateModel.emit({ property: 'firstColumnSizeRatio', value: $any($event.target).value })"> </mat-form-field> + + + + <mat-form-field *ngIf="combinedProperties.borderStyle !== undefined" + appearance="fill"> + <mat-label>{{'propertiesPanel.borderStyle' | translate }}</mat-label> + <mat-select [value]="combinedProperties.borderStyle" + (selectionChange)="updateModel.emit({ property: 'borderStyle', value: $event.value })"> + <mat-option *ngFor="let option of ['hidden', 'solid', 'dotted', 'dashed', + 'double', 'groove', 'ridge', 'inset', 'outset']" + [value]="option"> + {{ 'propertiesPanel.' + option | translate }} + </mat-option> + </mat-select> + </mat-form-field> + + <mat-form-field *ngIf="combinedProperties.borderColor !== undefined" + appearance="fill" class="mdInput textsingleline"> + <mat-label>{{'propertiesPanel.borderColor' | translate }}</mat-label> + <input matInput type="color" [value]="combinedProperties.borderColor" + (input)="updateModel.emit({ property: 'borderColor', value: $any($event.target).value })"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.borderColor !== undefined" + appearance="fill" class="mdInput textsingleline"> + <mat-label>{{'propertiesPanel.borderColor' | translate }}</mat-label> + <input matInput type="text" [value]="combinedProperties.borderColor" + (input)="updateModel.emit({ property: 'borderColor', value: $any($event.target).value })"> + </mat-form-field> + + <mat-form-field *ngIf="combinedProperties.borderWidth !== undefined" + appearance="fill" class="mdInput textsingleline"> + <mat-label>{{'propertiesPanel.borderWidth' | translate }}</mat-label> + <input matInput type="number" #borderWidth="ngModel" min="0" + [ngModel]="combinedProperties.borderWidth" + (ngModelChange)="updateModel.emit({ property: 'borderWidth', + value: $event, + isInputValid: borderWidth.valid && $event !== null })"> + </mat-form-field> </div> -- GitLab