From 8393cf46eb6d4a3ee3f8a017e5fe2b344dd6b340 Mon Sep 17 00:00:00 2001 From: David Godin Date: Mon, 13 Apr 2020 02:03:30 -0400 Subject: [PATCH 1/3] Baseline --- .../widget-numeric.component.ts | 64 +++++++------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/src/app/widget-numeric/widget-numeric.component.ts b/src/app/widget-numeric/widget-numeric.component.ts index 6e075f44..55a5b467 100644 --- a/src/app/widget-numeric/widget-numeric.component.ts +++ b/src/app/widget-numeric/widget-numeric.component.ts @@ -1,16 +1,12 @@ -import { Component, Input, OnInit, OnDestroy, Inject, ViewChild, ElementRef, AfterViewChecked } from '@angular/core'; +import { Component, Input, OnInit, OnDestroy, ViewChild, ElementRef, AfterViewChecked } from '@angular/core'; import { Subscription } from 'rxjs'; -import { MatDialog,MatDialogRef,MAT_DIALOG_DATA } from '@angular/material'; +import { MatDialog } from '@angular/material'; import { ModalWidgetComponent } from '../modal-widget/modal-widget.component'; -import { SignalKService, pathObject } from '../signalk.service'; +import { SignalKService } from '../signalk.service'; import { WidgetManagerService, IWidget, IWidgetConfig } from '../widget-manager.service'; import { UnitsService } from '../units.service'; import { isNumeric } from 'rxjs/util/isNumeric'; -import { isNull } from '@angular/compiler/src/output/output_ast'; - - - const defaultConfig: IWidgetConfig = { widgetLabel: null, @@ -44,10 +40,10 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck @ViewChild('canvasEl') canvasEl: ElementRef; @ViewChild('canvasBG') canvasBG: ElementRef; @ViewChild('wrapperDiv') wrapperDiv: ElementRef; - + activeWidget: IWidget; config: IWidgetConfig; - + dataValue: number = null; maxValue: number = null; minValue: number = null; @@ -57,10 +53,9 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck valueFontSize: number = 1; minMaxFontSize: number = 1; - //subs valueSub: Subscription = null; - + canvasCtx; canvasBGCtx; @@ -84,7 +79,7 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck this.canvasCtx = this.canvasEl.nativeElement.getContext('2d'); this.canvasBGCtx = this.canvasBG.nativeElement.getContext('2d'); - this.resizeWidget(); + this.resizeWidget(); } ngOnDestroy() { @@ -97,13 +92,13 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck resizeWidget() { let rect = this.wrapperDiv.nativeElement.getBoundingClientRect(); - + if (rect.height < 50) { return; } if (rect.width < 50) { return; } - if ((this.canvasEl.nativeElement.width != Math.floor(rect.width)) || (this.canvasEl.nativeElement.height != Math.floor(rect.height))) { - this.canvasEl.nativeElement.width = Math.floor(rect.width); + if ((this.canvasEl.nativeElement.width != Math.floor(rect.width)) || (this.canvasEl.nativeElement.height != Math.floor(rect.height))) { + this.canvasEl.nativeElement.width = Math.floor(rect.width); this.canvasEl.nativeElement.height = Math.floor(rect.height); - this.canvasBG.nativeElement.width = Math.floor(rect.width); + this.canvasBG.nativeElement.width = Math.floor(rect.width); this.canvasBG.nativeElement.height = Math.floor(rect.height); this.currentValueLength = 0; //will force resetting the font size this.currentMinMaxLength = 0; @@ -120,7 +115,7 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck this.valueSub = this.SignalKService.subscribePath(this.widgetUUID, this.config.paths['numericPath'].path, this.config.paths['numericPath'].source).subscribe( newValue => { this.dataValue = newValue; - // init min/max + // init min/max if (this.minValue === null) { this.minValue = this.dataValue; } if (this.maxValue === null) { this.maxValue = this.dataValue; } if (this.dataValue > this.maxValue) { this.maxValue = this.dataValue; } @@ -156,13 +151,8 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck this.subscribePath(); this.updateCanvas(); this.updateCanvasBG(); - } - }); - - - } /* ******************************************************************************************* */ @@ -197,15 +187,15 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck let maxTextWidth = Math.floor(this.canvasEl.nativeElement.width - (this.canvasEl.nativeElement.width * 0.15)); let maxTextHeight = Math.floor(this.canvasEl.nativeElement.height - (this.canvasEl.nativeElement.height * 0.2)); let valueText : string; - + if (isNumeric(this.dataValue)) { let converted = this.UnitsService.convertUnit(this.config.units['numericPath'], this.dataValue); - if (isNumeric(converted)) { // retest as convert stuff might have returned a text string + if (isNumeric(converted)) { // retest as convert stuff might have returned a text string valueText = this.padValue(converted.toFixed(this.config.numDecimal), this.config.numInt, this.config.numDecimal); } else { valueText = converted; } - + } else { valueText = "--"; } @@ -213,7 +203,7 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck if (this.currentValueLength != valueText.length) { //we need to set font size... this.currentValueLength = valueText.length; - + //TODO: at high res.large area, this can take way too long :( (500ms+) (added skip by 10 which helps, still feel it could be better...) // set font small and make bigger until we hit a max. this.valueFontSize = 1; @@ -222,14 +212,14 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck while ( (this.canvasCtx.measureText(valueText).width < maxTextWidth) && (this.valueFontSize < maxTextHeight)) { this.valueFontSize = this.valueFontSize + 10; this.canvasCtx.font = "bold " + this.valueFontSize.toString() + "px Arial"; - } + } // now decrease by 1 to find the right size while ( (this.canvasCtx.measureText(valueText).width < maxTextWidth) && (this.valueFontSize < maxTextHeight)) { this.valueFontSize--; this.canvasCtx.font = "bold " + this.valueFontSize.toString() + "px Arial"; } } - + this.canvasCtx.font = "bold " + this.valueFontSize.toString() + "px Arial"; this.canvasCtx.textAlign = "center"; this.canvasCtx.textBaseline="middle"; @@ -264,7 +254,7 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck var maxTextWidth = Math.floor(this.canvasEl.nativeElement.width - (this.canvasEl.nativeElement.width * 0.8)); var maxTextHeight = Math.floor(this.canvasEl.nativeElement.height - (this.canvasEl.nativeElement.height * 0.8)); // set font small and make bigger until we hit a max. - + var fontSize = 1; this.canvasBGCtx.fillStyle = window.getComputedStyle(this.wrapperDiv.nativeElement).color; this.canvasBGCtx.font = "bold " + fontSize.toString() + "px Arial"; // need to init it so we do loop at least once :) @@ -281,19 +271,17 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck if (!this.config.showMin && !this.config.showMax) { return; } //no need to do anything if we're not showing min/max - - let valueText: string = ''; - + if (this.config.showMin) { if (isNumeric(this.minValue)) { let converted = this.UnitsService.convertUnit(this.config.units['numericPath'], this.minValue); - if (isNumeric(converted)) { // retest as convert stuff might have returned a text string + if (isNumeric(converted)) { // retest as convert stuff might have returned a text string valueText = valueText + " Min: " + this.padValue(converted.toFixed(this.config.numDecimal), this.config.numInt, this.config.numDecimal); } else { valueText = valueText + " Min: " + converted; - } - + } + } else { valueText = valueText + " Min: --"; } @@ -301,7 +289,7 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck if (this.config.showMax) { if (isNumeric(this.maxValue)) { let converted = this.UnitsService.convertUnit(this.config.units['numericPath'], this.maxValue); - if (isNumeric(converted)) { // retest as convert stuff might have returned a text string + if (isNumeric(converted)) { // retest as convert stuff might have returned a text string valueText = valueText + " Max: " + this.padValue(converted.toFixed(this.config.numDecimal), this.config.numInt, this.config.numDecimal); } else { valueText = valueText + " Max: " + converted; @@ -358,8 +346,4 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck return strVal; } - - - - } From c9c3d199fc63ebfef74b864e41f8cb6742459c8d Mon Sep 17 00:00:00 2001 From: David Godin Date: Mon, 13 Apr 2020 02:13:49 -0400 Subject: [PATCH 2/3] Added theme event to redraw title and unit on theme change --- .../widget-numeric.component.ts | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/app/widget-numeric/widget-numeric.component.ts b/src/app/widget-numeric/widget-numeric.component.ts index 55a5b467..ba09adee 100644 --- a/src/app/widget-numeric/widget-numeric.component.ts +++ b/src/app/widget-numeric/widget-numeric.component.ts @@ -6,6 +6,7 @@ import { ModalWidgetComponent } from '../modal-widget/modal-widget.component'; import { SignalKService } from '../signalk.service'; import { WidgetManagerService, IWidget, IWidgetConfig } from '../widget-manager.service'; import { UnitsService } from '../units.service'; +import { AppSettingsService } from '../app-settings.service'; import { isNumeric } from 'rxjs/util/isNumeric'; const defaultConfig: IWidgetConfig = { @@ -56,6 +57,9 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck //subs valueSub: Subscription = null; + // dynamics theme support + themeNameSub: Subscription = null; + canvasCtx; canvasBGCtx; @@ -63,7 +67,9 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck public dialog:MatDialog, private SignalKService: SignalKService, private WidgetManagerService: WidgetManagerService, - private UnitsService: UnitsService) { + private UnitsService: UnitsService, + private AppSettingsService: AppSettingsService, // need for theme change subscription + ) { } ngOnInit() { @@ -76,6 +82,7 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck this.config = this.activeWidget.config; } this.subscribePath(); + this.subscribeTheme(); this.canvasCtx = this.canvasEl.nativeElement.getContext('2d'); this.canvasBGCtx = this.canvasBG.nativeElement.getContext('2d'); @@ -84,6 +91,7 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck ngOnDestroy() { this.unsubscribePath(); + this.unsubscribeTheme(); } ngAfterViewChecked() { @@ -134,6 +142,24 @@ export class WidgetNumericComponent implements OnInit, OnDestroy, AfterViewCheck } } +// Subscribe to theme event +subscribeTheme() { + this.themeNameSub = this.AppSettingsService.getThemeNameAsO().subscribe( + themeChange => { + setTimeout(() => { // need a delay so browser getComputedStyles has time to complete theme application. + this.drawTitle(); + this.drawUnit(); + }, 100); + }) +} + +unsubscribeTheme(){ + if (this.themeNameSub !== null) { + this.themeNameSub.unsubscribe(); + this.themeNameSub = null; + } +} + openWidgetSettings() { let dialogRef = this.dialog.open(ModalWidgetComponent, { From 0e3c2d05dbdba3c0fc08dd1abbe915417cbc67fd Mon Sep 17 00:00:00 2001 From: David Godin Date: Thu, 16 Apr 2020 00:17:12 -0400 Subject: [PATCH 3/3] Fix: Widget config form validator View error --- .../modal-widget/modal-widget.component.ts | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/app/modal-widget/modal-widget.component.ts b/src/app/modal-widget/modal-widget.component.ts index bb5de9a2..17908266 100644 --- a/src/app/modal-widget/modal-widget.component.ts +++ b/src/app/modal-widget/modal-widget.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit, Inject } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; -import { MatDialog,MatDialogRef,MAT_DIALOG_DATA } from '@angular/material'; +import { MatDialogRef,MAT_DIALOG_DATA } from '@angular/material'; import { DataSetService, IDataSet } from '../data-set.service'; import { IWidgetConfig } from '../widget-manager.service'; @@ -16,14 +16,11 @@ export class ModalWidgetComponent implements OnInit { formMaster: FormGroup; availableDataSets: IDataSet[]; - - constructor( public dialogRef:MatDialogRef, private DataSetService: DataSetService, - @Inject(MAT_DIALOG_DATA) public widgetConfig: IWidgetConfig) { } - - + @Inject(MAT_DIALOG_DATA) public widgetConfig: IWidgetConfig + ) { } ngOnInit() { //load datasets @@ -33,25 +30,30 @@ export class ModalWidgetComponent implements OnInit { this.formMaster.updateValueAndValidity(); } - generateFormGroups(formData: Object): FormGroup { let groups = new FormGroup({}); Object.keys(formData).forEach (key => { if ( (typeof(formData[key]) == 'object') && (formData[key] !== null) ) { groups.addControl(key, this.generateFormGroups(formData[key])); } else { - groups.addControl(key, new FormControl(formData[key])); + // Use switch in case we need more then Required form validator at some point. + switch (key) { + case "path": groups.addControl(key, new FormControl(formData[key], Validators.required)); + break; + + case "dataSetUUID": groups.addControl(key, new FormControl(formData[key], Validators.required)); + break; + + default: groups.addControl(key, new FormControl(formData[key])); + break; + } } - + }); return groups; } - submitConfig() { this.dialogRef.close(this.formMaster.value); } - - - }