From 7626dd2e8504b6173858db79254f266a49de87cd Mon Sep 17 00:00:00 2001 From: rhenck <richard.henck@iqb.hu-berlin.de> Date: Thu, 10 Mar 2022 17:16:10 +0100 Subject: [PATCH] [editor] Refactor dynamic grid view Now uses the implicit grid in auto mode. --- projects/editor/src/app/app.module.ts | 6 +- .../page-view/canvas/canvas.component.html | 6 +- .../dynamic-section-helper-grid.component.ts | 153 ++++++++++++++++ .../element-grid-change-listener.directive.ts | 20 ++ .../canvas/section-dynamic.component.ts | 125 ++++--------- .../canvas/section-menu.component.ts | 171 ++++++++++-------- projects/editor/src/assets/i18n/de.json | 3 +- 7 files changed, 308 insertions(+), 176 deletions(-) create mode 100644 projects/editor/src/app/components/unit-view/page-view/canvas/dynamic-section-helper-grid.component.ts create mode 100644 projects/editor/src/app/components/unit-view/page-view/canvas/element-grid-change-listener.directive.ts diff --git a/projects/editor/src/app/app.module.ts b/projects/editor/src/app/app.module.ts index 71b9bec7b..5bb043572 100644 --- a/projects/editor/src/app/app.module.ts +++ b/projects/editor/src/app/app.module.ts @@ -59,6 +59,8 @@ import { ElementStylePropertiesComponent } from './components/unit-view/page-view/properties-panel/style-properties-tab/element-style-properties.component'; import { ElementModelPropertiesComponent } from './components/unit-view/page-view/properties-panel/model-properties-tab/element-model-properties.component'; +import { DynamicSectionHelperGridComponent } from './components/unit-view/page-view/canvas/dynamic-section-helper-grid.component'; +import { ElementGridChangeListenerDirective } from './components/unit-view/page-view/canvas/element-grid-change-listener.directive'; @NgModule({ declarations: [ @@ -89,7 +91,9 @@ import { ElementModelPropertiesComponent } from ElementModelPropertiesComponent, DropListOptionEditDialogComponent, PositionFieldSetComponent, - DimensionFieldSetComponent + DimensionFieldSetComponent, + DynamicSectionHelperGridComponent, + ElementGridChangeListenerDirective ], imports: [ BrowserModule, diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/canvas.component.html b/projects/editor/src/app/components/unit-view/page-view/canvas/canvas.component.html index 73d7963ef..3f7e70675 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/canvas.component.html +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/canvas.component.html @@ -1,7 +1,7 @@ <div class="canvasBackground" fxFlex (click)="selectionService.clearElementSelection()"> <div class="canvasFrame" - [style.width.px]="page.hasMaxWidth ? page.maxWidth : 900" + [style.width.px]="page.hasMaxWidth ? page.maxWidth : null" [style.padding.px]="page.margin" [style.background-color]="page.backgroundColor"> <div cdkDropListGroup> @@ -48,9 +48,7 @@ </div> <button mat-fab class="add-section-button" - [style.width.px]="page.hasMaxWidth ? page.maxWidth : 900" - [style.margin-left.px]="page.margin" - [style.margin-right.px]="page.margin" + [style.width.px]="page.hasMaxWidth ? page.maxWidth : null" (click)="addSection()"> <mat-icon>add</mat-icon> </button> diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/dynamic-section-helper-grid.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/dynamic-section-helper-grid.component.ts new file mode 100644 index 000000000..f44024a46 --- /dev/null +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/dynamic-section-helper-grid.component.ts @@ -0,0 +1,153 @@ +import { CdkDragDrop } from '@angular/cdk/drag-drop/drag-events'; +import { + ChangeDetectorRef, + Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges +} from '@angular/core'; +import { UIElement, UIElementType } from '../../../../../../../common/interfaces/elements'; +import { UnitService } from '../../../../services/unit.service'; +import { Section } from '../../../../../../../common/interfaces/unit'; + +@Component({ + selector: '[app-dynamic-section-helper-grid]', + template: ` + <ng-container *ngFor="let column of columnCountArray; let x = index"> + <ng-container *ngFor="let row of rowCountArray; let y = index"> + <div class="grid-placeholder" + [style.grid-column-start]="x + 1" + [style.grid-column-end]="x + 1" + [style.grid-row-start]="y + 1" + [style.grid-row-end]="y + 1" + cdkDropList [cdkDropListData]="{ sectionIndex: sectionIndex, gridCoordinates: [x + 1, y + 1] }" + (cdkDropListDropped)="drop($any($event))" + id="list-{{sectionIndex}}-{{x+1}}-{{y+1}}" + (dragover)="$event.preventDefault()" + (drop)="newElementDropped( $event, x + 1, y + 1)"> + {{x + 1}} / {{y + 1}} + </div> + </ng-container> + </ng-container> + + <ng-content></ng-content> + `, + styles: [ + '.grid-placeholder {border: 5px solid aliceblue; color: lightblue; text-align: center;}' + ] +}) +export class DynamicSectionHelperGridComponent implements OnInit, OnChanges { + @Input() autoColumnSize!: boolean; + @Input() autoRowSize!: boolean; + @Input() gridColumnSizes!: string; + @Input() gridRowSizes!: string; + @Input() section!: Section; + @Input() sectionIndex!: number; + @Output() transferElement = new EventEmitter<{ previousSectionIndex: number, newSectionIndex: number }>(); + + columnCountArray: unknown[] = []; + rowCountArray: unknown[] = []; + + constructor(public unitService: UnitService) {} + + ngOnInit(): void { + this.calculateColumnCount(); + this.calculateRowCount(); + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.autoColumnSize || + changes.gridColumnSizes || + changes.gridRowSizes) { + this.calculateColumnCount(); + this.calculateRowCount(); + } + } + + refresh(): void { + this.calculateColumnCount(); + this.calculateRowCount(); + } + + private calculateColumnCount(): void { + let numberOfColumns; + if (this.autoColumnSize) { + numberOfColumns = this.section.elements + .reduce((accumulator, currentValue) => Math.max(accumulator, currentValue.position.gridColumnEnd as number), + 0) - 1; + } else { + numberOfColumns = this.gridColumnSizes.split(' ').length; + } + this.columnCountArray = Array(Math.max(numberOfColumns, 1)); + } + + private calculateRowCount(): void { + let numberOfRows; + if (this.autoRowSize) { + numberOfRows = this.section.elements + .reduce((accumulator, currentValue) => Math.max(accumulator, currentValue.position.gridRowEnd as number), + 0) - 1; + } else { + numberOfRows = this.gridRowSizes.split(' ').length; + } + this.rowCountArray = Array(Math.max(numberOfRows, 1)); + } + + drop(event: CdkDragDrop<{ sectionIndex: number; gridCoordinates?: number[]; }>): void { + const dragItemData: { dragType: string; element: UIElement; } = event.item.data; + + // Move element to other section - handled by parent (page-canvas). + if (event.previousContainer.data.sectionIndex !== event.container.data.sectionIndex) { + this.transferElement.emit({ + previousSectionIndex: event.previousContainer.data.sectionIndex, + newSectionIndex: event.container.data.sectionIndex + }); + } + if (dragItemData.dragType === 'move') { + const elementColumnRange: number = + event.item.data.element.position.gridColumnEnd - event.item.data.element.position.gridColumnStart; + const elementRowRange: number = + event.item.data.element.position.gridRowEnd - event.item.data.element.position.gridRowStart; + this.unitService.updateElementProperty( + [event.item.data.element], + 'gridColumnStart', + event.container.data.gridCoordinates![0] + ); + // Ensure the end value is at least the same as the start, otherwise the grid breaks. + this.unitService.updateElementProperty( + [dragItemData.element], + 'gridColumnEnd', + event.container.data.gridCoordinates![0] + elementColumnRange + ); + this.unitService.updateElementProperty( + [dragItemData.element], + 'gridRowStart', + event.container.data.gridCoordinates![1] + ); + this.unitService.updateElementProperty( + [dragItemData.element], + 'gridRowEnd', + event.container.data.gridCoordinates![1] + elementRowRange + ); + } else if (event.item.data.dragType === 'resize') { + this.unitService.updateElementProperty( + [dragItemData.element], + 'gridColumnEnd', + event.container.data.gridCoordinates![0] + 1 + ); + this.unitService.updateElementProperty( + [dragItemData.element], + 'gridRowEnd', + event.container.data.gridCoordinates![1] + 1 + ); + } else { + throw new Error('Unknown drop event'); + } + } + + newElementDropped(event: DragEvent, gridX: number, gridY: number): void { + event.preventDefault(); + this.unitService.addElementToSection( + event.dataTransfer?.getData('elementType') as UIElementType, + this.section, + { x: gridX, y: gridY } + ); + } +} diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/element-grid-change-listener.directive.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/element-grid-change-listener.directive.ts new file mode 100644 index 000000000..5378abece --- /dev/null +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/element-grid-change-listener.directive.ts @@ -0,0 +1,20 @@ +import { + Directive, EventEmitter, Input, OnChanges, Output +} from '@angular/core'; + +@Directive({ + selector: '[appElementGridChangeListener]' +}) +export class ElementGridChangeListenerDirective implements OnChanges { + @Input() autoColumnSize!: boolean; + @Input() gridColumnStart!: number; + @Input() gridColumnEnd!: number; + @Input() gridRowStart!: number; + @Input() gridRowEnd!: number; + + @Output() elementChanged = new EventEmitter(); + + ngOnChanges(): void { + this.elementChanged.emit(); + } +} diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/section-dynamic.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/section-dynamic.component.ts index 963768cbb..11e320851 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/section-dynamic.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/section-dynamic.component.ts @@ -1,11 +1,14 @@ import { - Component, Input, Output, EventEmitter, ViewChildren, QueryList + Component, + Input, + Output, + EventEmitter, + ViewChildren, + QueryList, ViewChild, ElementRef } from '@angular/core'; -import { CdkDragDrop } from '@angular/cdk/drag-drop/drag-events'; -import { UnitService } from '../../../../services/unit.service'; import { CanvasElementOverlay } from './overlays/canvas-element-overlay'; import { Section } from '../../../../../../../common/interfaces/unit'; -import { UIElement, UIElementType } from '../../../../../../../common/interfaces/elements'; +import { DynamicSectionHelperGridComponent } from './dynamic-section-helper-grid.component'; @Component({ selector: 'aspect-section-dynamic', @@ -13,30 +16,23 @@ import { UIElement, UIElementType } from '../../../../../../../common/interfaces <div [style.display]="'grid'" [style.grid-template-columns]="section.autoColumnSize ? '' : section.gridColumnSizes" [style.grid-template-rows]="section.autoRowSize ? '' : section.gridRowSizes" - [style.height.%]="100" + [style.grid-auto-columns]="'auto'" + [style.grid-auto-rows]="'auto'" cdkDropListGroup [style.border]="isSelected ? '2px solid #ff4081': '1px dotted'" - [style.height.px]="section.height" - [style.background-color]="section.backgroundColor"> - - <!-- Dynamic sections have the droplists for the grid cells next to the actual elements. Elements can not - be children of the grid cells because they can span over multiple cells. --> - <ng-container *ngFor="let column of this.section.gridColumnSizes.split(' '); let x = index"> - <ng-container *ngFor="let row of this.section.gridRowSizes.split(' '); let y = index"> - <div class="grid-placeholder" - [style.grid-column-start]="x + 1" - [style.grid-column-end]="x + 1" - [style.grid-row-start]="y + 1" - [style.grid-row-end]="y + 1" - cdkDropList [cdkDropListData]="{ sectionIndex: sectionIndex, gridCoordinates: [x + 1, y + 1] }" - (cdkDropListDropped)="drop($any($event))" - id="list-{{sectionIndex}}-{{x+1}}-{{y+1}}" - (dragover)="$event.preventDefault()" (drop)="newElementDropped($event, x + 1, y + 1)"> - {{x + 1}} / {{y + 1}} - </div> - </ng-container> - </ng-container> + [style.min-height.px]="section.autoRowSize ? 50 : section.height" + [style.background-color]="section.backgroundColor" + app-dynamic-section-helper-grid + [autoColumnSize]="section.autoColumnSize" + [autoRowSize]="section.autoRowSize" + [gridColumnSizes]="section.gridColumnSizes" + [gridRowSizes]="section.gridRowSizes" + [section]="section" + [sectionIndex]="sectionIndex" + (transferElement)="transferElement.emit($event)"> + <!-- Angular content projection is used in the helper grid component, where the following + is the content.--> <aspect-dynamic-canvas-overlay *ngFor="let element of section.elements" #elementComponent [element]="$any(element)" @@ -53,15 +49,18 @@ import { UIElement, UIElementType } from '../../../../../../../common/interfaces cdkDropList cdkDropListSortingDisabled [cdkDropListData]="{ sectionIndex: sectionIndex }" [cdkDropListConnectedTo]="dropListList" - (resize)="resizeOverlay($event)" [style.position]="'relative'" - [style.pointer-events]="dragging ? 'none' : 'auto'"> + [style.pointer-events]="dragging ? 'none' : 'auto'" + appElementGridChangeListener + [gridColumnStart]="element.position.gridColumnStart" + [gridColumnEnd]="element.position.gridColumnEnd" + [gridRowStart]="element.position.gridRowStart" + [gridRowEnd]="element.position.gridRowEnd" + (resize)="resizeOverlay($event)" + (elementChanged)="helperGrid?.refresh()"> </aspect-dynamic-canvas-overlay> </div> - `, - styles: [ - '.grid-placeholder {border: 5px solid aliceblue; color: lightblue; text-align: center;}' - ] + ` }) export class SectionDynamicComponent { @Input() section!: Section; @@ -70,73 +69,11 @@ export class SectionDynamicComponent { @Input() isSelected!: boolean; @Output() transferElement = new EventEmitter<{ previousSectionIndex: number, newSectionIndex: number }>(); + @ViewChild(DynamicSectionHelperGridComponent) helperGrid!: DynamicSectionHelperGridComponent; @ViewChildren('elementComponent') childElementComponents!: QueryList<CanvasElementOverlay>; dragging = false; - constructor(public unitService: UnitService) { } - - drop(event: CdkDragDrop<{ sectionIndex: number; gridCoordinates?: number[]; }>): void { - const dragItemData: { dragType: string; element: UIElement; } = event.item.data; - - // Move element to other section - handled by parent (page-canvas). - if (event.previousContainer.data.sectionIndex !== event.container.data.sectionIndex) { - this.transferElement.emit({ - previousSectionIndex: event.previousContainer.data.sectionIndex, - newSectionIndex: event.container.data.sectionIndex - }); - } - if (dragItemData.dragType === 'move') { - const elementColumnRange: number = - event.item.data.element.position.gridColumnEnd - event.item.data.element.position.gridColumnStart; - const elementRowRange: number = - event.item.data.element.position.gridRowEnd - event.item.data.element.position.gridRowStart; - this.unitService.updateElementProperty( - [event.item.data.element], - 'gridColumnStart', - event.container.data.gridCoordinates![0] - ); - // Ensure the end value is at least the same as the start, otherwise the grid breaks. - this.unitService.updateElementProperty( - [dragItemData.element], - 'gridColumnEnd', - event.container.data.gridCoordinates![0] + elementColumnRange - ); - this.unitService.updateElementProperty( - [dragItemData.element], - 'gridRowStart', - event.container.data.gridCoordinates![1] - ); - this.unitService.updateElementProperty( - [dragItemData.element], - 'gridRowEnd', - event.container.data.gridCoordinates![1] + elementRowRange - ); - } else if (event.item.data.dragType === 'resize') { - this.unitService.updateElementProperty( - [dragItemData.element], - 'gridColumnEnd', - event.container.data.gridCoordinates![0] + 1 - ); - this.unitService.updateElementProperty( - [dragItemData.element], - 'gridRowEnd', - event.container.data.gridCoordinates![1] + 1 - ); - } else { - throw new Error('Unknown drop event'); - } - } - - newElementDropped(event: DragEvent, gridX: number, gridY: number): void { - event.preventDefault(); - this.unitService.addElementToSection( - event.dataTransfer?.getData('elementType') as UIElementType, - this.section, - { x: gridX, y: gridY } - ); - } - resizeOverlay(event: { dragging: boolean, elementWidth?: number, elementHeight?: number }): void { this.dragging = event.dragging; } diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts index 8611d95f8..54324c69f 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts @@ -18,26 +18,16 @@ import { UIElement } from '../../../../../../../common/interfaces/elements'; </button> <mat-menu #elementListMenu="matMenu" class="layoutMenu" xPosition="before"> <mat-action-list> + <ng-container *ngIf="section.elements.length === 0"> + Keine Elemente im Abschnitt + </ng-container> <mat-list-item *ngFor="let element of section.elements" - (click)="selectElement(element)"> + (click)="selectElement(element)"> {{element.id}} </mat-list-item> </mat-action-list> </mat-menu> - <button mat-mini-fab [matMenuTriggerFor]="heightMenu"> - <mat-icon>height</mat-icon> - </button> - <mat-menu #heightMenu="matMenu" class="layoutMenu" xPosition="before"> - <div (click)="$event.stopPropagation()"> - <mat-form-field appearance="fill"> - <mat-label>{{'section-menu.height' | translate }}</mat-label> - <input matInput mat-menu-item type="number" - [value]="$any(section.height)" - (click)="$any($event).stopPropagation()" - (change)="updateModel('height', $any($event.target).value)"> - </mat-form-field> - </div> - </mat-menu> + <button mat-mini-fab (click)="openColorPicker()"> <mat-icon>palette</mat-icon> @@ -51,76 +41,105 @@ import { UIElement } from '../../../../../../../common/interfaces/elements'; </button> <mat-menu #layoutMenu="matMenu" class="layoutMenu" xPosition="before"> <div (click)="$event.stopPropagation()"> - <mat-checkbox class="menuItem" [checked]="section.dynamicPositioning" - (click)="$any($event).stopPropagation()" - (change)="updateModel('dynamicPositioning', $event.checked)"> - {{'section-menu.dynamic-positioning' | translate }} - </mat-checkbox> + <mat-checkbox class="menuItem" [checked]="section.dynamicPositioning" + (click)="$any($event).stopPropagation()" + (change)="updateModel('dynamicPositioning', $event.checked)"> + {{'section-menu.dynamic-positioning' | translate }} + </mat-checkbox> + <ng-container *ngIf="!section.dynamicPositioning"> + <mat-form-field appearance="fill"> + <mat-label>{{'section-menu.height' | translate }}</mat-label> + <input matInput mat-menu-item type="number" + [value]="$any(section.height)" + (click)="$any($event).stopPropagation()" + (change)="updateModel('height', $any($event.target).value)"> + </mat-form-field> + </ng-container> <div *ngIf="section.dynamicPositioning"> - {{'section-menu.columns' | translate }} - <div class="size-group"> - <mat-form-field> - <mat-label>{{'section-menu.amount' | translate }}</mat-label> - <input matInput type="number" - [value]="$any(section.gridColumnSizes.split(' ').length)" - (click)="$any($event).stopPropagation()" - (change)="modifySizeArray('gridColumnSizes', $any($event).target.value)"> - </mat-form-field> - <mat-checkbox class="menuItem" [checked]="section.autoColumnSize" - (click)="$any($event).stopPropagation()" - (change)="updateModel('autoColumnSize', $event.checked)"> - {{'section-menu.autoColumnSize' | translate }} - </mat-checkbox> - <ng-container *ngIf="!section.autoColumnSize"> - <div *ngFor="let size of columnSizes ; let i = index" class="size-inputs" fxLayout="row"> + <fieldset> + <legend>{{'section-menu.columns' | translate }}</legend> + + <div class="size-group"> + <mat-checkbox class="menuItem" [checked]="section.autoColumnSize" + (click)="$any($event).stopPropagation()" + (change)="updateModel('autoColumnSize', $event.checked)"> + {{'section-menu.autoColumnSize' | translate }} + </mat-checkbox> + <ng-container *ngIf="!section.autoColumnSize"> <mat-form-field> - <mat-label>{{'section-menu.width' | translate }} {{i + 1}}</mat-label> + <mat-label>{{'section-menu.columnCount' | translate }}</mat-label> <input matInput type="number" - [value]="size.value" + [value]="$any(section.gridColumnSizes.split(' ').length)" (click)="$any($event).stopPropagation()" - (change)="changeGridSize('gridColumnSizes', i, false, $any($event).target.value)"> + (change)="modifySizeArray('gridColumnSizes', $any($event).target.value)"> </mat-form-field> - <mat-select [value]="size.unit" + <div *ngFor="let size of columnSizes ; let i = index" class="size-inputs" fxLayout="row"> + <mat-form-field> + <mat-label>{{'section-menu.width' | translate }} {{i + 1}}</mat-label> + <input matInput type="number" + [value]="size.value" + (click)="$any($event).stopPropagation()" + (change)="changeGridSize('gridColumnSizes', i, false, $any($event).target.value)"> + </mat-form-field> + <mat-select [value]="size.unit" + (click)="$any($event).stopPropagation()" + (selectionChange)="changeGridSize('gridColumnSizes', i, true, $event.value)"> + <mat-option value="fr">{{'section-menu.fraction' | translate }}</mat-option> + <mat-option value="px">{{'section-menu.pixel' | translate }}</mat-option> + </mat-select> + </div> + </ng-container> + </div> + </fieldset> + + <fieldset> + <legend>{{'section-menu.rows' | translate }}</legend> + <div class="size-group"> + <mat-checkbox class="menuItem" [checked]="section.autoRowSize" (click)="$any($event).stopPropagation()" - (selectionChange)="changeGridSize('gridColumnSizes', i, true, $event.value)"> - <mat-option value="fr">{{'section-menu.fraction' | translate }}</mat-option> - <mat-option value="px">{{'section-menu.pixel' | translate }}</mat-option> - </mat-select> - </div> - </ng-container> - </div> - {{'section-menu.rows' | translate }} - <div class="size-group"> - <mat-form-field> - <mat-label>{{'section-menu.amount' | translate }}</mat-label> - <input matInput type="number" - [value]="$any(section.gridRowSizes.split(' ').length)" - (click)="$any($event).stopPropagation()" - (change)="modifySizeArray('gridRowSizes', $any($event).target.value)"> - </mat-form-field> - <mat-checkbox class="menuItem" [checked]="section.autoRowSize" - (click)="$any($event).stopPropagation()" - (change)="updateModel('autoRowSize', $event.checked)"> - {{'section-menu.autoRowSize' | translate }} - </mat-checkbox> - <ng-container *ngIf="!section.autoRowSize"> - <div *ngFor="let size of rowSizes ; let i = index" class="size-inputs" fxLayout="row"> + (change)="updateModel('autoRowSize', $event.checked)"> + {{'section-menu.autoRowSize' | translate }} + </mat-checkbox> + <ng-container *ngIf="!section.autoRowSize"> + + <mat-form-field appearance="fill"> + <mat-label>{{'section-menu.height' | translate }}</mat-label> + <input matInput mat-menu-item type="number" + [value]="$any(section.height)" + (click)="$any($event).stopPropagation()" + (change)="updateModel('height', $any($event.target).value)"> + </mat-form-field> + <mat-form-field> - <mat-label>{{'section-menu.height' | translate }} {{i + 1}}</mat-label> + <mat-label>{{'section-menu.rowCount' | translate }}</mat-label> <input matInput type="number" - [value]="size.value" + [value]="$any(section.gridRowSizes.split(' ').length)" (click)="$any($event).stopPropagation()" - (change)="changeGridSize('gridRowSizes', i, false, $any($event).target.value)"> + (change)="modifySizeArray('gridRowSizes', $any($event).target.value)"> </mat-form-field> - <mat-select [value]="size.unit" - (click)="$any($event).stopPropagation()" - (selectionChange)="changeGridSize('gridRowSizes', i, true, $event.value)"> - <mat-option value="fr">{{'section-menu.fraction' | translate }}</mat-option> - <mat-option value="px">{{'section-menu.pixel' | translate }}</mat-option> - </mat-select> - </div> - </ng-container> - </div> + + + <fieldset> + <legend>Zeilenhöhen</legend> + <div *ngFor="let size of rowSizes ; let i = index" class="size-inputs" fxLayout="row"> + <mat-form-field> + <mat-label>{{'section-menu.height' | translate }} {{i + 1}}</mat-label> + <input matInput type="number" + [value]="size.value" + (click)="$any($event).stopPropagation()" + (change)="changeGridSize('gridRowSizes', i, false, $any($event).target.value)"> + </mat-form-field> + <mat-select [value]="size.unit" + (click)="$any($event).stopPropagation()" + (selectionChange)="changeGridSize('gridRowSizes', i, true, $event.value)"> + <mat-option value="fr">{{'section-menu.fraction' | translate }}</mat-option> + <mat-option value="px">{{'section-menu.pixel' | translate }}</mat-option> + </mat-select> + </div> + </fieldset> + </ng-container> + </div> + </fieldset> </div> </div> </mat-menu> @@ -146,7 +165,7 @@ import { UIElement } from '../../../../../../../common/interfaces/elements'; '::ng-deep .layoutMenu .size-inputs .mat-form-field-infix {width: 65px}', '.size-group {background-color: #f5f5f5; margin: 0 0 15px 0}', '::ng-deep .layoutMenu .size-group mat-select {padding-top: 24px; padding-left: 15px;}', - '::ng-deep .layoutMenu {width: 200px; padding: 0 15px}' + '::ng-deep .layoutMenu {padding: 0 15px}' ] }) export class SectionMenuComponent implements OnInit, OnDestroy { diff --git a/projects/editor/src/assets/i18n/de.json b/projects/editor/src/assets/i18n/de.json index a7bb8bf76..0bf327a45 100644 --- a/projects/editor/src/assets/i18n/de.json +++ b/projects/editor/src/assets/i18n/de.json @@ -195,7 +195,8 @@ "dynamic-positioning": "dynamisches Layout", "columns": "Spalten", "rows": "Zeilen", - "amount": "Anzahl", + "columnCount": "Anzahl der Spalten", + "rowCount": "Anzahl der Zeilen", "autoColumnSize": "dynamische Breite", "autoRowSize": "dynamische Höhe", "width": "Breite", -- GitLab