Merge pull request #4742 from FinnStutzenstein/autonomicSlides
Partially scale and scroll the motion slide
This commit is contained in:
commit
484d9b23e0
@ -7,7 +7,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50px;
|
left: 50px;
|
||||||
top: 50px;
|
top: 50px;
|
||||||
line-height: 1.5em;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#slide {
|
#slide {
|
||||||
|
@ -8,6 +8,7 @@ import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
|||||||
import { SlideData } from 'app/core/core-services/projector-data.service';
|
import { SlideData } from 'app/core/core-services/projector-data.service';
|
||||||
import { ProjectorElement } from 'app/shared/models/core/projector';
|
import { ProjectorElement } from 'app/shared/models/core/projector';
|
||||||
import { ViewProjector } from 'app/site/projector/models/view-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 } {
|
function hasError(obj: object): obj is { error: string } {
|
||||||
return (<{ error: string }>obj).error !== undefined;
|
return (<{ error: string }>obj).error !== undefined;
|
||||||
@ -28,6 +29,13 @@ export class SlideContainerComponent extends BaseComponent {
|
|||||||
private slide: ViewContainerRef;
|
private slide: ViewContainerRef;
|
||||||
private slideRef: ComponentRef<BaseSlideComponent<object>>;
|
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.
|
* The data for this slide. Will be accessed below.
|
||||||
*/
|
*/
|
||||||
@ -59,8 +67,9 @@ export class SlideContainerComponent extends BaseComponent {
|
|||||||
if (this.previousSlideName !== slideData.element.name) {
|
if (this.previousSlideName !== slideData.element.name) {
|
||||||
this.slideChanged(slideData.element);
|
this.slideChanged(slideData.element);
|
||||||
this.previousSlideName = slideData.element.name;
|
this.previousSlideName = slideData.element.name;
|
||||||
|
} else {
|
||||||
|
this.setDataForComponent();
|
||||||
}
|
}
|
||||||
this.setDataForComponent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get slideData(): SlideData<object> {
|
public get slideData(): SlideData<object> {
|
||||||
@ -77,6 +86,7 @@ export class SlideContainerComponent extends BaseComponent {
|
|||||||
this._projector = projector;
|
this._projector = projector;
|
||||||
this.setProjectorForComponent();
|
this.setProjectorForComponent();
|
||||||
this.updateScroll();
|
this.updateScroll();
|
||||||
|
this.updateScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get projector(): ViewProjector {
|
public get projector(): ViewProjector {
|
||||||
@ -101,18 +111,19 @@ export class SlideContainerComponent extends BaseComponent {
|
|||||||
return this._scroll;
|
return this._scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _scale: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the slideStyle, when the scale changes.
|
* Update the slideStyle, when the scale changes.
|
||||||
*/
|
*/
|
||||||
@Input()
|
@Input()
|
||||||
public set scale(value: number) {
|
public set scale(value: number) {
|
||||||
if (this.slideOptions.scaleable) {
|
this._scale = value;
|
||||||
value *= 10;
|
this.updateScale();
|
||||||
value += 100;
|
}
|
||||||
this.slideStyle['font-size'] = `${value}%`;
|
|
||||||
} else {
|
public get scale(): number {
|
||||||
this.slideStyle['font-size'] = '100%';
|
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 {
|
private updateScroll(): void {
|
||||||
if (this.slideOptions.scrollable) {
|
if (this.slideOptions.scrollable && !this.slideIsAutonomic) {
|
||||||
let value = this.scroll;
|
let value = this.scroll;
|
||||||
value *= -100;
|
value *= -100;
|
||||||
if (this.projector.show_header_footer) {
|
if (this.projector.show_header_footer) {
|
||||||
@ -145,6 +157,28 @@ export class SlideContainerComponent extends BaseComponent {
|
|||||||
this.slideStyle['margin-top'] = `${value}px`;
|
this.slideStyle['margin-top'] = `${value}px`;
|
||||||
} else {
|
} else {
|
||||||
this.slideStyle['margin-top'] = '0px';
|
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.slideRef = this.slide.createComponent(slideFactory);
|
||||||
this.setDataForComponent();
|
this.setDataForComponent();
|
||||||
this.setProjectorForComponent();
|
this.setProjectorForComponent();
|
||||||
|
this.updateScale();
|
||||||
|
this.updateScroll();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
client/src/app/slides/base-scale-scroll-slide-component.ts
Normal file
32
client/src/app/slides/base-scale-scroll-slide-component.ts
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<div *ngIf="data">
|
<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 -->
|
<!-- Submitters -->
|
||||||
<h3 translate>Submitters</h3>
|
<h3 translate>Submitters</h3>
|
||||||
<span *ngFor="let submitter of data.data.submitter; let last = last">
|
<span *ngFor="let submitter of data.data.submitter; let last = last">
|
||||||
@ -13,13 +13,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</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 -->
|
<!-- Title -->
|
||||||
|
<div class="spacer" [ngStyle]="{height: projector.show_header_footer ? '50px' : '0'}"></div>
|
||||||
<div class="slidetitle">
|
<div class="slidetitle">
|
||||||
<h1>{{ data.data.title }}</h1>
|
<h1>{{ data.data.title }}</h1>
|
||||||
<h2><span translate>Motion</span> {{ data.data.identifier }}</h2>
|
<h2><span translate>Motion</span> {{ data.data.identifier }}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="text-wrapper">
|
||||||
|
<div id="text" [ngStyle]="textDivStyles">
|
||||||
<!-- Text -->
|
<!-- Text -->
|
||||||
<span class="text-prefix-label">{{ preamble | translate }}</span>
|
<span class="text-prefix-label">{{ preamble | translate }}</span>
|
||||||
|
|
||||||
@ -73,4 +77,5 @@
|
|||||||
<div [innerHTML]="data.data.reason"></div>
|
<div [innerHTML]="data.data.reason"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,10 +4,22 @@
|
|||||||
opacity: 0.5;
|
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 {
|
#sidebox {
|
||||||
width: 260px;
|
width: 260px;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin-top: 94px;
|
|
||||||
background: #d3d3d3;
|
background: #d3d3d3;
|
||||||
border-radius: 7px 0 0 7px;
|
border-radius: 7px 0 0 7px;
|
||||||
padding: 3px 7px 10px 10px;
|
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 */
|
/* override the absolute position of outside linenumbers on motion slide */
|
||||||
:host ::ng-deep .motion-text {
|
:host ::ng-deep .motion-text {
|
||||||
&.line-numbers-outside {
|
&.line-numbers-outside {
|
||||||
.os-line-number {
|
.os-line-number {
|
||||||
&:after {
|
&:after {
|
||||||
top: 19px;
|
top: 19px;
|
||||||
font-size: 13px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,15 @@ import { SlideData } from '../../../core/core-services/projector-data.service';
|
|||||||
import { MotionSlideObjAmendmentParagraph } from './motion-slide-obj-amendment-paragraph';
|
import { MotionSlideObjAmendmentParagraph } from './motion-slide-obj-amendment-paragraph';
|
||||||
import { BaseMotionSlideComponent } from '../base/base-motion-slide';
|
import { BaseMotionSlideComponent } from '../base/base-motion-slide';
|
||||||
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
||||||
|
import { IBaseScaleScrollSlideComponent } from 'app/slides/base-scale-scroll-slide-component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'os-motion-slide',
|
selector: 'os-motion-slide',
|
||||||
templateUrl: './motion-slide.component.html',
|
templateUrl: './motion-slide.component.html',
|
||||||
styleUrls: ['./motion-slide.component.scss']
|
styleUrls: ['./motion-slide.component.scss']
|
||||||
})
|
})
|
||||||
export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideData> {
|
export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideData>
|
||||||
|
implements IBaseScaleScrollSlideComponent<MotionSlideData> {
|
||||||
/**
|
/**
|
||||||
* Indicates the LineNumberingMode Mode.
|
* Indicates the LineNumberingMode Mode.
|
||||||
*/
|
*/
|
||||||
@ -61,6 +63,8 @@ export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideDa
|
|||||||
this.preamble = value.data.preamble;
|
this.preamble = value.data.preamble;
|
||||||
this.crMode = value.element.mode || 'original';
|
this.crMode = value.element.mode || 'original';
|
||||||
|
|
||||||
|
this.textDivStyles.width = value.data.show_meta_box ? 'calc(100% - 250px)' : '100%';
|
||||||
|
|
||||||
this.recalcUnifiedChanges();
|
this.recalcUnifiedChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +72,42 @@ export class MotionSlideComponent extends BaseMotionSlideComponent<MotionSlideDa
|
|||||||
return this._data;
|
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(
|
public constructor(
|
||||||
translate: TranslateService,
|
translate: TranslateService,
|
||||||
motionRepo: MotionRepositoryService,
|
motionRepo: MotionRepositoryService,
|
||||||
|
Loading…
Reference in New Issue
Block a user