Removable footer, compact styling for particle creator
This commit is contained in:
@@ -1,12 +1,27 @@
|
||||
<div class="card-div">
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>Frames</mat-card-title>
|
||||
<mat-card-header class="frame-header-fullwidth">
|
||||
<div class="frame-header-row" mat-card-title>
|
||||
<span class="frame-title-text">Frames</span>
|
||||
<div>
|
||||
<ng-content></ng-content>
|
||||
<button mat-icon-button color="warn" (click)="removeFrame(currentFrame)"
|
||||
matTooltip="Delete {{currentFrame}}"
|
||||
[disabled]="frames.length <= 1">
|
||||
<mat-icon [class.can-delete]="frames.length > 1" [class.can-not-delete]="frames.length <= 1">
|
||||
delete
|
||||
</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="addFrame()" matTooltip="Add Frame">
|
||||
<mat-icon class="add-button">add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="frames-container">
|
||||
<mat-tab-group [selectedIndex]="frames.indexOf(currentFrame)"
|
||||
(selectedIndexChange)="switchFrame(frames[$event])">
|
||||
(selectedIndexChange)="switchFrame(frames[$event])">
|
||||
@for (frameId of frames; track frameId) {
|
||||
<mat-tab [label]="frameId">
|
||||
<div class="frame-content">
|
||||
@@ -33,21 +48,10 @@
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="frame-actions">
|
||||
<button mat-raised-button color="warn" (click)="removeFrame(frameId)"
|
||||
[disabled]="frames.length <= 1">
|
||||
Remove Frame
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
}
|
||||
</mat-tab-group>
|
||||
<div class="add-frame">
|
||||
<button mat-raised-button color="primary" (click)="addFrame()">
|
||||
Add New Frame
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
@@ -6,6 +6,36 @@
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-mdc-card-header-text {
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.frame-header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.frame-title-text {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.add-button {
|
||||
color: green
|
||||
}
|
||||
|
||||
.can-delete {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.can-not-delete {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.particles-list {
|
||||
height: 550px;
|
||||
overflow-y: auto;
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FramesComponent } from './frames.component';
|
||||
|
||||
describe('FramesComponent', () => {
|
||||
let component: FramesComponent;
|
||||
let fixture: ComponentFixture<FramesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [FramesComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(FramesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {MatButton, MatIconButton} from "@angular/material/button";
|
||||
import {Component, inject} from '@angular/core';
|
||||
import {MatIconButton} from "@angular/material/button";
|
||||
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card";
|
||||
import {MatTab, MatTabGroup} from "@angular/material/tabs";
|
||||
|
||||
@@ -7,11 +7,11 @@ import {ParticleData} from '../../models/particle.model';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {ParticleManagerService} from '../../services/particle-manager.service';
|
||||
import {FrameManagerService} from '../../services/frame-manager.service';
|
||||
import {MatTooltipModule} from '@angular/material/tooltip';
|
||||
|
||||
@Component({
|
||||
selector: 'app-frames',
|
||||
imports: [
|
||||
MatButton,
|
||||
MatCard,
|
||||
MatCardContent,
|
||||
MatCardHeader,
|
||||
@@ -19,17 +19,15 @@ import {FrameManagerService} from '../../services/frame-manager.service';
|
||||
MatIcon,
|
||||
MatIconButton,
|
||||
MatTab,
|
||||
MatTabGroup
|
||||
],
|
||||
MatTabGroup,
|
||||
MatTooltipModule,
|
||||
],
|
||||
templateUrl: './frames.component.html',
|
||||
styleUrl: './frames.component.scss'
|
||||
})
|
||||
export class FramesComponent {
|
||||
|
||||
constructor(
|
||||
private particleManagerService: ParticleManagerService,
|
||||
private frameManagerService: FrameManagerService) {
|
||||
}
|
||||
private particleManagerService = inject(ParticleManagerService);
|
||||
private frameManagerService = inject(FrameManagerService);
|
||||
|
||||
/**
|
||||
* Get the particle data
|
||||
|
||||
@@ -6,35 +6,35 @@
|
||||
</app-header>
|
||||
|
||||
<main>
|
||||
<section class="darkmodeSection">
|
||||
<section class="column">
|
||||
<div class="renderer-section column">
|
||||
<div class="flex row">
|
||||
<div class="flex side-column">
|
||||
<app-particle-properties></app-particle-properties>
|
||||
</div>
|
||||
<div class="flex middle-column">
|
||||
<app-render-container></app-render-container>
|
||||
<div class="plane-controls">
|
||||
<label>Plane Position (Z-axis):</label>
|
||||
<mat-slider [min]="minOffset" [max]="maxOffset" step="1" #planeSlider>
|
||||
<input matSliderThumb [(ngModel)]="planePosition" (input)="updatePlanePosition($event)">
|
||||
</mat-slider>
|
||||
<span>{{ planePosition }} offset from center</span>
|
||||
<app-full-size [hideFooter]="true">
|
||||
<section class="darkmodeSection full-height">
|
||||
<section class="column">
|
||||
<div class="renderer-section column">
|
||||
<div class="flex row">
|
||||
<div class="flex side-column">
|
||||
<app-particle-properties></app-particle-properties>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex side-column">
|
||||
<app-particle></app-particle>
|
||||
<app-frames></app-frames>
|
||||
<div>
|
||||
<button mat-fab extended (click)="copyJson()">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
Copy JSON to clipboard
|
||||
</button>
|
||||
<div class="flex middle-column">
|
||||
<app-render-container></app-render-container>
|
||||
<div class="plane-controls">
|
||||
<label>Plane Position (Z-axis):</label>
|
||||
<mat-slider [min]="minOffset" [max]="maxOffset" step="1" #planeSlider>
|
||||
<input matSliderThumb [(ngModel)]="planePosition" (input)="updatePlanePosition($event)">
|
||||
</mat-slider>
|
||||
<span>{{ planePosition }} offset from center</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex side-column">
|
||||
<app-particle></app-particle>
|
||||
<app-frames>
|
||||
<button mat-icon-button matTooltip="Copy JSON to clipboard" (click)="copyJson()">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
</button>
|
||||
</app-frames>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</app-full-size>
|
||||
</main>
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ParticlesComponent } from './particles.component';
|
||||
|
||||
describe('ParticlesComponent', () => {
|
||||
let component: ParticlesComponent;
|
||||
let fixture: ComponentFixture<ParticlesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ParticlesComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ParticlesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Component, ElementRef, ViewChild} from '@angular/core';
|
||||
import {Component, ElementRef, inject, ViewChild} from '@angular/core';
|
||||
|
||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {MatButtonModule} from '@angular/material/button';
|
||||
@@ -23,6 +23,8 @@ import {FramesComponent} from './components/frames/frames.component';
|
||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||
import {RenderContainerComponent} from './components/render-container/render-container.component';
|
||||
import {ParticlesService} from '@api';
|
||||
import {MatTooltipModule} from '@angular/material/tooltip';
|
||||
import {FullSizeComponent} from '@shared-components/full-size/full-size.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-particles',
|
||||
@@ -43,21 +45,20 @@ import {ParticlesService} from '@api';
|
||||
PropertiesComponent,
|
||||
ParticleComponent,
|
||||
FramesComponent,
|
||||
RenderContainerComponent
|
||||
],
|
||||
RenderContainerComponent,
|
||||
MatTooltipModule,
|
||||
FullSizeComponent
|
||||
],
|
||||
templateUrl: './particles.component.html',
|
||||
styleUrl: './particles.component.scss'
|
||||
})
|
||||
export class ParticlesComponent {
|
||||
@ViewChild('planeSlider') planeSlider!: ElementRef;
|
||||
|
||||
constructor(
|
||||
private intersectionPlaneService: IntersectionPlaneService,
|
||||
private particleManagerService: ParticleManagerService,
|
||||
private matSnackBar: MatSnackBar,
|
||||
private particlesService: ParticlesService,
|
||||
) {
|
||||
}
|
||||
private readonly intersectionPlaneService = inject(IntersectionPlaneService);
|
||||
private readonly particleManagerService = inject(ParticleManagerService);
|
||||
private readonly matSnackBar = inject(MatSnackBar);
|
||||
private readonly particlesService = inject(ParticlesService);
|
||||
|
||||
/**
|
||||
* Update plane position based on slider
|
||||
|
||||
Reference in New Issue
Block a user