Merge pull request #4742 from FinnStutzenstein/autonomicSlides

Partially scale and scroll the motion slide
This commit is contained in:
Emanuel Schütze 2019-05-27 22:43:40 +02:00 committed by GitHub
commit 484d9b23e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 153 additions and 16 deletions

View File

@ -7,7 +7,7 @@
position: absolute;
left: 50px;
top: 50px;
line-height: 1.5em;
line-height: 1.5;
}
}
#slide {

View File

@ -8,6 +8,7 @@ import { BaseSlideComponent } from 'app/slides/base-slide-component';
import { SlideData } from 'app/core/core-services/projector-data.service';
import { ProjectorElement } from 'app/shared/models/core/projector';
import { ViewProjector } from 'app/site/projector/models/view-projector';
import { isBaseScaleScrollSlideComponent } from 'app/slides/base-scale-scroll-slide-component';
function hasError(obj: object): obj is { error: string } {
return (<{ error: string }>obj).error !== undefined;
@ -28,6 +29,13 @@ export class SlideContainerComponent extends BaseComponent {
private slide: ViewContainerRef;
private slideRef: ComponentRef<BaseSlideComponent<object>>;
/**
* A slide is autonomic, if it takes care of scaling and scrolling by itself.
*/
private get slideIsAutonomic(): boolean {
return !!this.slideRef && !!this.slideRef.instance && isBaseScaleScrollSlideComponent(this.slideRef.instance);
}
/**
* The data for this slide. Will be accessed below.
*/
@ -59,8 +67,9 @@ export class SlideContainerComponent extends BaseComponent {
if (this.previousSlideName !== slideData.element.name) {
this.slideChanged(slideData.element);
this.previousSlideName = slideData.element.name;
} else {
this.setDataForComponent();
}
this.setDataForComponent();
}
public get slideData(): SlideData<object> {
@ -77,6 +86,7 @@ export class SlideContainerComponent extends BaseComponent {
this._projector = projector;
this.setProjectorForComponent();
this.updateScroll();
this.updateScale();
}
public get projector(): ViewProjector {
@ -101,18 +111,19 @@ export class SlideContainerComponent extends BaseComponent {
return this._scroll;
}
private _scale: number;
/**
* Update the slideStyle, when the scale changes.
*/
@Input()
public set scale(value: number) {
if (this.slideOptions.scaleable) {
value *= 10;
value += 100;
this.slideStyle['font-size'] = `${value}%`;
} else {
this.slideStyle['font-size'] = '100%';
}
this._scale = value;
this.updateScale();
}
public get scale(): number {
return this._scale;
}
/**
@ -133,10 +144,11 @@ export class SlideContainerComponent extends BaseComponent {
}
/**
* Updates the 'margin-top' attribute in the slide styles.
* Updates the 'margin-top' attribute in the slide styles. Propages the sroll to
* autonomic slides.
*/
private updateScroll(): void {
if (this.slideOptions.scrollable) {
if (this.slideOptions.scrollable && !this.slideIsAutonomic) {
let value = this.scroll;
value *= -100;
if (this.projector.show_header_footer) {
@ -145,6 +157,28 @@ export class SlideContainerComponent extends BaseComponent {
this.slideStyle['margin-top'] = `${value}px`;
} else {
this.slideStyle['margin-top'] = '0px';
if (this.slideIsAutonomic && isBaseScaleScrollSlideComponent(this.slideRef.instance)) {
this.slideRef.instance.scroll = this.scroll;
}
}
}
/**
* Updates the 'font-size' style attributes. Propagates the scale to autonomic slides.
*/
private updateScale(): void {
if (this.slideOptions.scaleable && !this.slideIsAutonomic) {
let scale = this.scale;
scale *= 10;
scale += 100;
this.slideStyle['font-size'] = `${scale}%`;
} else {
this.slideStyle['font-size'] = '100%';
if (this.slideIsAutonomic && isBaseScaleScrollSlideComponent(this.slideRef.instance)) {
this.slideRef.instance.scale = this.scale;
}
}
}
@ -170,6 +204,8 @@ export class SlideContainerComponent extends BaseComponent {
this.slideRef = this.slide.createComponent(slideFactory);
this.setDataForComponent();
this.setProjectorForComponent();
this.updateScale();
this.updateScroll();
});
}

View File

@ -0,0 +1,32 @@
import { Input } from '@angular/core';
import { BaseSlideComponent } from './base-slide-component';
export function isBaseScaleScrollSlideComponent<T extends object>(obj: any): obj is IBaseScaleScrollSlideComponent<T> {
return !!obj && obj.scroll !== undefined && obj.scale !== undefined;
}
/**
* A description of BaseScaleScrollSlideComponent. Usefull for "multi"-inheritance.
*/
export interface IBaseScaleScrollSlideComponent<T extends object> extends BaseSlideComponent<T> {
scroll: number;
scale: number;
}
/**
* A base slide component, which is autonomic with respect to scaling and srolling, meaning
* that the slide itself (and not the slide container) will take care of this.
*/
export abstract class BaseScaleScrollSlideComponent<T extends object> extends BaseSlideComponent<T>
implements IBaseScaleScrollSlideComponent<T> {
@Input()
public scroll: number;
@Input()
public scale: number;
public constructor() {
super();
}
}

View File

@ -1,5 +1,5 @@
<div *ngIf="data">
<div id="sidebox" *ngIf="data.data.show_meta_box">
<div id="sidebox" *ngIf="data.data.show_meta_box" [ngStyle]="{'margin-top': projector.show_header_footer ? '144px' : '94px'}">
<!-- Submitters -->
<h3 translate>Submitters</h3>
<span *ngFor="let submitter of data.data.submitter; let last = last">
@ -13,13 +13,17 @@
</div>
</div>
<div [ngStyle]="{'width': data.data.show_meta_box ? 'calc(100% - 250px)' : '100%'}">
<div [ngStyle]="{width: data.data.show_meta_box ? 'calc(100% - 250px)' : '100%'}">
<!-- Title -->
<div class="spacer" [ngStyle]="{height: projector.show_header_footer ? '50px' : '0'}"></div>
<div class="slidetitle">
<h1>{{ data.data.title }}</h1>
<h2><span translate>Motion</span> {{ data.data.identifier }}</h2>
</div>
</div>
<div id="text-wrapper">
<div id="text" [ngStyle]="textDivStyles">
<!-- Text -->
<span class="text-prefix-label">{{ preamble | translate }}</span>
@ -73,4 +77,5 @@
<div [innerHTML]="data.data.reason"></div>
</div>
</div>
</div>
</div>

View File

@ -4,10 +4,22 @@
opacity: 0.5;
}
/**
* Override some special values which will be set dynamically
*/
.slidetitle {
/* Original: 40px: This is done in the `scroll()` method, so the
* motion text will be cut (to be taken by word) on the grey line */
margin-bottom: 0px !important;
h1 {
margin: 0 !important;
}
}
#sidebox {
width: 260px;
right: 0;
margin-top: 94px;
background: #d3d3d3;
border-radius: 7px 0 0 7px;
padding: 3px 7px 10px 10px;
@ -21,13 +33,25 @@
}
}
.spacer {
min-width: 1px;
}
#text-wrapper {
overflow: hidden;
}
#text {
position: relative;
}
/* override the absolute position of outside linenumbers on motion slide */
:host ::ng-deep .motion-text {
&.line-numbers-outside {
.os-line-number {
&:after {
top: 19px;
font-size: 13px;
font-size: 15px;
}
}
}

View File

@ -13,13 +13,15 @@ import { SlideData } from '../../../core/core-services/projector-data.service';
import { MotionSlideObjAmendmentParagraph } from './motion-slide-obj-amendment-paragraph';
import { BaseMotionSlideComponent } from '../base/base-motion-slide';
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
import { IBaseScaleScrollSlideComponent } from 'app/slides/base-scale-scroll-slide-component';
@Component({
selector: 'os-motion-slide',
templateUrl: './motion-slide.component.html',
styleUrls: ['./motion-slide.component.scss']
})
export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideData> {
export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideData>
implements IBaseScaleScrollSlideComponent<MotionSlideData> {
/**
* Indicates the LineNumberingMode Mode.
*/
@ -61,6 +63,8 @@ export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideDa
this.preamble = value.data.preamble;
this.crMode = value.element.mode || 'original';
this.textDivStyles.width = value.data.show_meta_box ? 'calc(100% - 250px)' : '100%';
this.recalcUnifiedChanges();
}
@ -68,6 +72,42 @@ export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideDa
return this._data;
}
private _scroll = 0;
@Input()
public set scroll(value: number) {
this._scroll = value;
value *= -100;
value += 40;
this.textDivStyles['margin-top'] = `${value}px`;
}
public get scroll(): number {
return this._scroll;
}
private _scale = 0;
@Input()
public set scale(value: number) {
this._scale = value;
value *= 10;
value += 100;
this.textDivStyles['font-size'] = `${value}%`;
}
public get scale(): number {
return this._scale;
}
public textDivStyles: {
width?: string;
'margin-top'?: string;
'font-size'?: string;
} = {};
public constructor(
translate: TranslateService,
motionRepo: MotionRepositoryService,