From 597cc0ae320aea06a4b1e5015e8fa116686cd459 Mon Sep 17 00:00:00 2001
From: David Simpson <45690499+davegarthsimpson@users.noreply.github.com>
Date: Mon, 18 Jul 2022 17:46:39 +0200
Subject: [PATCH 1/4] add typing support to steppers
---
.../dialogs/settings/settings-component.tsx | 61 ++++-----
.../dialogs/settings/settings-step-input.tsx | 122 ++++++++++++++++++
.../src/browser/style/index.css | 1 +
.../src/browser/style/settings-step-input.css | 47 +++++++
4 files changed, 198 insertions(+), 33 deletions(-)
create mode 100644 arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
create mode 100644 arduino-ide-extension/src/browser/style/settings-step-input.css
diff --git a/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx b/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx
index ff70947ff..620cd1982 100644
--- a/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx
+++ b/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx
@@ -21,7 +21,15 @@ import {
AsyncLocalizationProvider,
LanguageInfo,
} from '@theia/core/lib/common/i18n/localization';
+import SettingsStepInput from './settings-step-input';
+const maxScale = 200;
+const minScale = -100;
+const scaleStep = 20;
+
+const maxFontSize = 72;
+const minFontSize = 8;
+const fontSizeStep = 2;
export class SettingsComponent extends React.Component<
SettingsComponent.Props,
SettingsComponent.State
@@ -88,6 +96,8 @@ export class SettingsComponent extends React.Component<
}
protected renderSettings(): React.ReactNode {
+ const scalePercentage = 100 + this.state.interfaceScale * 20;
+
return (
{nls.localize(
@@ -160,14 +170,13 @@ export class SettingsComponent extends React.Component<
-
@@ -179,14 +188,13 @@ export class SettingsComponent extends React.Component<
/>
{nls.localize('arduino/preferences/automatic', 'Automatic')}
-
%
@@ -516,13 +524,8 @@ export class SettingsComponent extends React.Component<
}
};
- protected editorFontSizeDidChange = (
- event: React.ChangeEvent
- ): void => {
- const { value } = event.target;
- if (value) {
- this.setState({ editorFontSize: parseInt(value, 10) });
- }
+ private setFontSize = (editorFontSize: number) => {
+ this.setState({ editorFontSize });
};
protected rawAdditionalUrlsValueDidChange = (
@@ -539,18 +542,10 @@ export class SettingsComponent extends React.Component<
this.setState({ autoScaleInterface: event.target.checked });
};
- protected interfaceScaleDidChange = (
- event: React.ChangeEvent
- ): void => {
- const { value } = event.target;
- const percentage = parseInt(value, 10);
- if (isNaN(percentage)) {
- return;
- }
+ private setInterfaceScale = (percentage: number) => {
const interfaceScale = (percentage - 100) / 20;
- if (!isNaN(interfaceScale)) {
- this.setState({ interfaceScale });
- }
+
+ this.setState({ interfaceScale });
};
protected verifyAfterUploadDidChange = (
diff --git a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
new file mode 100644
index 000000000..d6f54ea7b
--- /dev/null
+++ b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
@@ -0,0 +1,122 @@
+import * as React from '@theia/core/shared/react';
+import classnames from 'classnames';
+
+interface SettingsStepInputProps {
+ value: number;
+ setSettingsStateValue: (interfaceScale: number) => void;
+ step: number;
+ maxValue: number;
+ minValue: number;
+ classNames?: { [key: string]: string };
+}
+
+const SettingsStepInput: React.FC = (
+ props: SettingsStepInputProps
+) => {
+ const { value, setSettingsStateValue, step, maxValue, minValue, classNames } =
+ props;
+
+ const [stepUpDisabled, setStepUpDisabled] = React.useState(false);
+ const [stepDownDisabled, setStepDownDisabled] = React.useState(false);
+
+ const onStepUp = (): void => {
+ const valueRoundedToScale = Math.ceil(value / step) * step;
+ const calculatedValue =
+ valueRoundedToScale === value ? value + step : valueRoundedToScale;
+ const newValue = limitValueByCondition(
+ calculatedValue,
+ calculatedValue >= maxValue,
+ () => setStepUpDisabled(true)
+ );
+
+ setSettingsStateValue(newValue);
+ };
+
+ const onStepDown = (): void => {
+ const valueRoundedToScale = Math.floor(value / step) * step;
+ const calculatedValue =
+ valueRoundedToScale === value ? value - step : valueRoundedToScale;
+ const newValue = limitValueByCondition(
+ calculatedValue,
+ calculatedValue <= minValue,
+ () => setStepDownDisabled(true)
+ );
+
+ setSettingsStateValue(newValue);
+ };
+
+ const limitValueByCondition = (
+ calculatedValue: number,
+ condition: boolean,
+ onConditionTrue: () => void,
+ onConditionFalse = enableButtons
+ ): number => {
+ if (condition) {
+ onConditionTrue();
+ return minValue;
+ } else {
+ onConditionFalse();
+ return calculatedValue;
+ }
+ };
+
+ const enableButtons = (): void => {
+ setStepUpDisabled(false);
+ setStepDownDisabled(false);
+ };
+
+ const onUserInput = (event: React.ChangeEvent): void => {
+ const { value: eventValue } = event.target;
+
+ if (eventValue === '') {
+ setSettingsStateValue(0);
+ }
+
+ const number = Number(eventValue);
+
+ if (!isNaN(number) && number !== value) {
+ let newValue;
+ if (number > value) {
+ newValue = limitValueByCondition(number, number >= maxValue, () =>
+ setStepUpDisabled(true)
+ );
+ } else {
+ newValue = limitValueByCondition(number, number <= minValue, () =>
+ setStepDownDisabled(true)
+ );
+ }
+
+ setSettingsStateValue(newValue);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default SettingsStepInput;
diff --git a/arduino-ide-extension/src/browser/style/index.css b/arduino-ide-extension/src/browser/style/index.css
index fe5d9753f..1a7c98533 100644
--- a/arduino-ide-extension/src/browser/style/index.css
+++ b/arduino-ide-extension/src/browser/style/index.css
@@ -18,6 +18,7 @@
@import './fonts.css';
@import './custom-codicon.css';
@import './progress-bar.css';
+@import './settings-step-input.css';
.theia-input.warning:focus {
outline-width: 1px;
diff --git a/arduino-ide-extension/src/browser/style/settings-step-input.css b/arduino-ide-extension/src/browser/style/settings-step-input.css
new file mode 100644
index 000000000..fd6d6046f
--- /dev/null
+++ b/arduino-ide-extension/src/browser/style/settings-step-input.css
@@ -0,0 +1,47 @@
+.settings-step-input-container {
+ position: relative
+}
+
+.settings-step-input-element::-webkit-inner-spin-button,
+.settings-step-input-element::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+.settings-step-input-buttons-container {
+ display: none;
+ flex-direction: column;
+ position: absolute;
+ right: 0px;
+ top: 50%;
+ transform: translate(0px, -50%);
+ height: calc(100% - 4px);
+ width: 14px;
+ padding: 2px;
+ background: white;
+}
+
+.settings-step-input-container:hover > .settings-step-input-buttons-container {
+ display: flex;
+}
+
+.settings-step-input-up-button {
+ transform: rotate(-180deg);
+}
+
+.settings-step-input-button {
+ border: none;
+ border-radius: 0;
+ height: 50%;
+ width: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ user-select: none;
+ cursor: pointer;
+ line-height: 12px;
+}
+
+.settings-step-input-button:hover {
+ background: rgba(128, 128, 128, 0.8);
+}
From c7971601f57bc41194c6e303b2988b6fc3a62c95 Mon Sep 17 00:00:00 2001
From: David Simpson <45690499+davegarthsimpson@users.noreply.github.com>
Date: Mon, 18 Jul 2022 18:08:51 +0200
Subject: [PATCH 2/4] logic cleanup
---
.../dialogs/settings/settings-step-input.tsx | 31 ++++++++++++++-----
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
index d6f54ea7b..d8de881fa 100644
--- a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
+++ b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
@@ -25,8 +25,9 @@ const SettingsStepInput: React.FC = (
valueRoundedToScale === value ? value + step : valueRoundedToScale;
const newValue = limitValueByCondition(
calculatedValue,
+ maxValue,
calculatedValue >= maxValue,
- () => setStepUpDisabled(true)
+ disableStepUp
);
setSettingsStateValue(newValue);
@@ -38,8 +39,9 @@ const SettingsStepInput: React.FC = (
valueRoundedToScale === value ? value - step : valueRoundedToScale;
const newValue = limitValueByCondition(
calculatedValue,
+ minValue,
calculatedValue <= minValue,
- () => setStepDownDisabled(true)
+ disableStepDown
);
setSettingsStateValue(newValue);
@@ -47,13 +49,14 @@ const SettingsStepInput: React.FC = (
const limitValueByCondition = (
calculatedValue: number,
+ limitedValue: number,
condition: boolean,
onConditionTrue: () => void,
onConditionFalse = enableButtons
): number => {
if (condition) {
onConditionTrue();
- return minValue;
+ return limitedValue;
} else {
onConditionFalse();
return calculatedValue;
@@ -65,6 +68,14 @@ const SettingsStepInput: React.FC = (
setStepDownDisabled(false);
};
+ const disableStepUp = (): void => {
+ setStepUpDisabled(true);
+ };
+
+ const disableStepDown = (): void => {
+ setStepDownDisabled(true);
+ };
+
const onUserInput = (event: React.ChangeEvent): void => {
const { value: eventValue } = event.target;
@@ -77,12 +88,18 @@ const SettingsStepInput: React.FC = (
if (!isNaN(number) && number !== value) {
let newValue;
if (number > value) {
- newValue = limitValueByCondition(number, number >= maxValue, () =>
- setStepUpDisabled(true)
+ newValue = limitValueByCondition(
+ number,
+ maxValue,
+ number >= maxValue,
+ disableStepUp
);
} else {
- newValue = limitValueByCondition(number, number <= minValue, () =>
- setStepDownDisabled(true)
+ newValue = limitValueByCondition(
+ number,
+ minValue,
+ number <= minValue,
+ disableStepDown
);
}
From c18850ba0f15cfb1db71445cdc4d257d641cb1d1 Mon Sep 17 00:00:00 2001
From: David Simpson <45690499+davegarthsimpson@users.noreply.github.com>
Date: Mon, 18 Jul 2022 18:18:49 +0200
Subject: [PATCH 3/4] misc cleanup
---
.../src/browser/dialogs/settings/settings-component.tsx | 2 +-
.../src/browser/dialogs/settings/settings-step-input.tsx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx b/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx
index 620cd1982..6bbc3c4c1 100644
--- a/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx
+++ b/arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx
@@ -28,7 +28,7 @@ const minScale = -100;
const scaleStep = 20;
const maxFontSize = 72;
-const minFontSize = 8;
+const minFontSize = 0;
const fontSizeStep = 2;
export class SettingsComponent extends React.Component<
SettingsComponent.Props,
diff --git a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
index d8de881fa..c7abfb5da 100644
--- a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
+++ b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
@@ -3,7 +3,7 @@ import classnames from 'classnames';
interface SettingsStepInputProps {
value: number;
- setSettingsStateValue: (interfaceScale: number) => void;
+ setSettingsStateValue: (value: number) => void;
step: number;
maxValue: number;
minValue: number;
From 0b2f390529dfa7bfc47f4d84d0ce522e2ebab749 Mon Sep 17 00:00:00 2001
From: David Simpson <45690499+davegarthsimpson@users.noreply.github.com>
Date: Tue, 19 Jul 2022 10:21:16 +0200
Subject: [PATCH 4/4] account for lack of unmount
---
.../src/browser/dialogs/settings/settings-step-input.tsx | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
index c7abfb5da..458266fa9 100644
--- a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
+++ b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx
@@ -107,6 +107,14 @@ const SettingsStepInput: React.FC = (
}
};
+ // the component does not unmount when we close the settings dialog
+ // in theia which necessitates the below useEffect
+ React.useEffect(() => {
+ if (value > minValue && value < maxValue) {
+ enableButtons();
+ }
+ }, [value, minValue, maxValue]);
+
return (