1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-06-13 13:04:03 +00:00

Added music & sound volume sliders in the settings menu

This commit is contained in:
Yoshie2000 2020-08-30 21:08:30 +02:00
parent 091401e52b
commit 1a0a3dbf2d
7 changed files with 249 additions and 110 deletions

View File

@ -1,5 +1,4 @@
// Common classes and style // Common classes and style
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -14,7 +13,6 @@ body {
overflow: hidden; overflow: hidden;
font-family: $mainFont; font-family: $mainFont;
font-synthesis: none; font-synthesis: none;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
@ -26,19 +24,15 @@ html {
position: fixed; position: fixed;
// scroll-behavior: smooth; // scroll-behavior: smooth;
background: $mainBgColor; background: $mainBgColor;
// Disable zooming and thus // Disable zooming and thus
-ms-touch-action: pan-x, pan-y; -ms-touch-action: pan-x, pan-y;
touch-action: pan-x, pan-y; touch-action: pan-x, pan-y;
-ms-content-zooming: none; -ms-content-zooming: none;
top: 0; top: 0;
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
background: #dee1ea; background: #dee1ea;
@include DarkThemeOverride { @include DarkThemeOverride {
background: $darkModeGameBackground; background: $darkModeGameBackground;
} }
@ -50,7 +44,6 @@ body {
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none; -ms-user-select: none;
background: inherit !important; background: inherit !important;
text-transform: none; text-transform: none;
white-space: normal; white-space: normal;
word-break: normal; word-break: normal;
@ -66,19 +59,17 @@ body {
scrollbar-width: 6px; scrollbar-width: 6px;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
// -webkit-overflow-scrolling: touch; /* stop scrolling immediately */ // -webkit-overflow-scrolling: touch; /* stop scrolling immediately */
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ -webkit-touch-callout: none;
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ /* prevent callout to copy image, etc when tap to hold */
-webkit-text-size-adjust: none;
/* prevent webkit from resizing text to fit */
// Internet explorer // Internet explorer
scrollbar-face-color: #888; scrollbar-face-color: #888;
scrollbar-track-color: rgba(255, 255, 255, 0.1); scrollbar-track-color: rgba(255, 255, 255, 0.1);
// Firefox // Firefox
scrollbar-color: #cdd0d4 rgba(#000, 0.05); scrollbar-color: #cdd0d4 rgba(#000, 0.05);
overflow: hidden; overflow: hidden;
@include Text; @include Text;
&.externalAdOpen { &.externalAdOpen {
&::before { &::before {
text-transform: uppercase; text-transform: uppercase;
@ -97,7 +88,6 @@ body {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
color: #fff; color: #fff;
@include InlineAnimation(1s ease-in-out infinite) { @include InlineAnimation(1s ease-in-out infinite) {
50% { 50% {
transform: scale(1.05); transform: scale(1.05);
@ -105,9 +95,7 @@ body {
} }
} }
} }
// For recording the bg video // For recording the bg video
// filter: blur(5px); // filter: blur(5px);
// &::after { // &::after {
// position: fixed; // position: fixed;
@ -122,20 +110,24 @@ body {
} }
img { img {
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ -webkit-touch-callout: none;
/* prevent callout to copy image, etc when tap to hold */
} }
i { i {
font-style: normal; font-style: normal;
} }
b, b,
strong { strong {
font-weight: normal; font-weight: normal;
} }
u, u,
a { a {
text-decoration: none; text-decoration: none;
} }
input, input,
textarea, textarea,
select { select {
@ -152,7 +144,6 @@ button {
cursor: pointer; cursor: pointer;
position: relative; position: relative;
@include TextShadow3D; @include TextShadow3D;
&.prefab_BuyButtonWithResources { &.prefab_BuyButtonWithResources {
display: flex; display: flex;
box-sizing: border-box; box-sizing: border-box;
@ -163,27 +154,23 @@ button {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@include S(width, 85px); @include S(width, 85px);
&.tooExpensive { &.tooExpensive {
color: $colorRedBright; color: $colorRedBright;
background-color: #555; background-color: #555;
cursor: default; cursor: default;
} }
.cost_entry { .cost_entry {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
b { b {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
&.tooExpensive { &.tooExpensive {
cursor: default !important; cursor: default !important;
background-color: #565859 !important; background-color: #565859 !important;
@ -214,7 +201,6 @@ button {
// color: $accentColorDark; // color: $accentColorDark;
letter-spacing: 0.05em !important; letter-spacing: 0.05em !important;
// box-shadow: 0 #{D(1px)} #{D(2px)} 0 rgba(0, 10, 20, 0.2); // box-shadow: 0 #{D(1px)} #{D(2px)} 0 rgba(0, 10, 20, 0.2);
.keybinding { .keybinding {
@include S(bottom, -2.5px); @include S(bottom, -2.5px);
@include S(right, -2px); @include S(right, -2px);
@ -226,10 +212,13 @@ button {
} }
::selection { ::selection {
background: $colorGreenBright; /* WebKit/Blink Browsers */ background: $colorGreenBright;
/* WebKit/Blink Browsers */
} }
::-moz-selection { ::-moz-selection {
background: $colorGreenBright; /* Gecko Browsers */ background: $colorGreenBright;
/* Gecko Browsers */
} }
input[type="text"], input[type="text"],
@ -244,35 +233,27 @@ input[type="email"] {
background: lighten($mainBgColor, 8); background: lighten($mainBgColor, 8);
color: #eee; color: #eee;
text-align: left; text-align: left;
user-select: text !important; user-select: text !important;
pointer-events: all !important; pointer-events: all !important;
@include Text; @include Text;
@include IncreasedClickArea(15px); @include IncreasedClickArea(15px);
@include S(border-radius, $globalBorderRadius); @include S(border-radius, $globalBorderRadius);
&::placeholder { &::placeholder {
color: #fff; color: #fff;
opacity: 0.4; opacity: 0.4;
} }
transition: background-color 0.1s ease-in-out !important; transition: background-color 0.1s ease-in-out !important;
@include TextShadow3D(#fff); @include TextShadow3D(#fff);
@include BoxShadow3D(lighten($mainBgColor, 30)); @include BoxShadow3D(lighten($mainBgColor, 30));
&:focus { &:focus {
@include BoxShadow3D(lighten($mainBgColor, 35)); @include BoxShadow3D(lighten($mainBgColor, 35));
} }
&.errored { &.errored {
@include BoxShadow3D(mix(lighten($mainBgColor, 30), #f77, 25%)); @include BoxShadow3D(mix(lighten($mainBgColor, 30), #f77, 25%));
&:focus { &:focus {
@include BoxShadow3D(mix(lighten($mainBgColor, 50), #f77, 25%)); @include BoxShadow3D(mix(lighten($mainBgColor, 50), #f77, 25%));
} }
} }
&.input-token { &.input-token {
@include SuperHeading; @include SuperHeading;
text-align: center; text-align: center;
@ -324,7 +305,6 @@ canvas {
// &.unsmoothed { // &.unsmoothed {
// } // }
letter-spacing: 0 !important; letter-spacing: 0 !important;
transform: translateZ(0); transform: translateZ(0);
backface-visibility: hidden; backface-visibility: hidden;
-webkit-backface-visibility: hidden; -webkit-backface-visibility: hidden;
@ -404,13 +384,11 @@ canvas {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
text-transform: uppercase; text-transform: uppercase;
@include Text; @include Text;
@include TextShadow3D; @include TextShadow3D;
opacity: 1; opacity: 1;
z-index: 20; z-index: 20;
color: #393747; color: #393747;
&::after { &::after {
content: " "; content: " ";
background: uiResource("loading.svg") center center / contain no-repeat; background: uiResource("loading.svg") center center / contain no-repeat;
@ -421,7 +399,6 @@ canvas {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
} }
@include DarkThemeOverride { @include DarkThemeOverride {
color: #fff; color: #fff;
} }
@ -443,7 +420,6 @@ canvas {
.prefab_FeatureComingSoon { .prefab_FeatureComingSoon {
position: relative; position: relative;
&::after { &::after {
@include S(top, -5px); @include S(top, -5px);
@include S(left, -5px); @include S(left, -5px);
@ -461,10 +437,8 @@ canvas {
@include PlainText; @include PlainText;
text-transform: uppercase; text-transform: uppercase;
} }
opacity: 0.6; opacity: 0.6;
>* {
> * {
opacity: 0.5 !important; opacity: 0.5 !important;
} }
} }
@ -488,14 +462,12 @@ canvas {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
.loadingImage { .loadingImage {
background: uiResource("loading.svg") center center / #{D(60px)} no-repeat; background: uiResource("loading.svg") center center / #{D(60px)} no-repeat;
width: 100%; width: 100%;
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
} }
.loadingStatus { .loadingStatus {
position: absolute; position: absolute;
@include S(left, 20px); @include S(left, 20px);
@ -503,13 +475,11 @@ canvas {
@include S(bottom, 30px); @include S(bottom, 30px);
@include Text; @include Text;
@include TextShadow3D(#aaa); @include TextShadow3D(#aaa);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
>.bar {
> .bar {
display: none; display: none;
@include S(margin-top, 15px); @include S(margin-top, 15px);
width: 80vw; width: 80vw;
@ -517,7 +487,6 @@ canvas {
position: relative; position: relative;
@include TextShadow3D(#fff); @include TextShadow3D(#fff);
height: 2px; height: 2px;
.inner { .inner {
position: absolute !important; position: absolute !important;
top: 0; top: 0;
@ -526,9 +495,7 @@ canvas {
z-index: 1; z-index: 1;
@include BoxShadow3D($themeColor, $size: 1px); @include BoxShadow3D($themeColor, $size: 1px);
@include S(border-radius, $globalBorderRadius); @include S(border-radius, $globalBorderRadius);
transform-origin: 0% 50%; transform-origin: 0% 50%;
@include InlineAnimation(1.3s ease-in-out infinite) { @include InlineAnimation(1.3s ease-in-out infinite) {
0% { 0% {
background-color: darken($themeColor, 5); background-color: darken($themeColor, 5);
@ -544,7 +511,6 @@ canvas {
} }
} }
} }
.status { .status {
display: none; display: none;
position: relative; position: relative;
@ -579,11 +545,9 @@ canvas {
&.loading { &.loading {
opacity: 0.2; opacity: 0.2;
} }
&:hover { &:hover {
background-color: darken($bgColor, 5); background-color: darken($bgColor, 5);
} }
.knob { .knob {
@include S(width, 20px); @include S(width, 20px);
@include S(height, 17px); @include S(height, 17px);
@ -594,20 +558,51 @@ canvas {
@include BorderRadius(20px); @include BorderRadius(20px);
@include BoxShadow3D(#fff, $size: 1px); @include BoxShadow3D(#fff, $size: 1px);
} }
&.checked { &.checked {
background-color: $themeColor; background-color: $themeColor;
@include BoxShadow3D($themeColor, $size: 2px); @include BoxShadow3D($themeColor, $size: 2px);
.knob { .knob {
@include S(margin-left, 15px); @include S(margin-left, 15px);
} }
&:hover { &:hover {
background-color: lighten($themeColor, 15); background-color: lighten($themeColor, 15);
} }
} }
} }
.range {
display: flex;
align-items: center;
justify-content: center;
}
.range-input {
cursor: pointer;
background-color: transparent;
width: 100px;
height: 10px;
transform: translate(7px, 2px);
&::-webkit-slider-runnable-track {
background-color: darken($mainBgColor, 3);
color: darken($mainBgColor, 3);
height: 16px;
border-radius: 8px;
}
&::-webkit-slider-thumb {
appearance: none;
-webkit-appearance: none;
box-shadow: inset 0 0 0 10px $themeColor;
background-color: transparent;
width: 20px;
height: 20px;
border-radius: 50%;
transition: 0.3s;
}
&:hover::-webkit-slider-thumb {
box-shadow: inset 0 0 0 10px lighten($themeColor, 15);
}
}
.keybinding { .keybinding {
background: #fff; background: #fff;
text-transform: uppercase; text-transform: uppercase;
@ -615,14 +610,13 @@ canvas {
@include PlainText; @include PlainText;
@include S(border-radius, $globalBorderRadius); @include S(border-radius, $globalBorderRadius);
&, &,
> span { >span {
@include S(font-size, 9px); @include S(font-size, 9px);
@include S(line-height, 11px); @include S(line-height, 11px);
font-weight: bold !important; font-weight: bold !important;
text-shadow: none !important; text-shadow: none !important;
// font-family: Arial, sans-serif !important; // font-family: Arial, sans-serif !important;
} }
font-weight: bold; font-weight: bold;
color: $accentColorDark; color: $accentColorDark;
text-align: center; text-align: center;
@ -638,7 +632,6 @@ canvas {
@include S(height, 12px); @include S(height, 12px);
overflow: hidden; overflow: hidden;
border: #{D(0px)} solid $accentColorDark; border: #{D(0px)} solid $accentColorDark;
.keybinding_space { .keybinding_space {
@include S(font-size, 17px); @include S(font-size, 17px);
@include S(line-height, 11px); @include S(line-height, 11px);
@ -651,7 +644,6 @@ canvas {
.xpaystation-widget-lightbox-overlay { .xpaystation-widget-lightbox-overlay {
background: rgba($mainBgColor, 0.94); background: rgba($mainBgColor, 0.94);
} }
&, &,
iframe { iframe {
pointer-events: all; pointer-events: all;
@ -692,9 +684,7 @@ iframe {
* { * {
pointer-events: all; pointer-events: all;
} }
background: rgba($mainBgColor, 0.94) !important; background: rgba($mainBgColor, 0.94) !important;
.cpmsvideoclosebanner { .cpmsvideoclosebanner {
font-family: GameFont !important; font-family: GameFont !important;
font-size: 16px !important; font-size: 16px !important;
@ -707,4 +697,4 @@ iframe {
transform: translateY(2px); transform: translateY(2px);
} }
} }
} }

View File

@ -146,9 +146,10 @@ class MusicInstance extends MusicInstanceInterface {
return this.playing; return this.playing;
} }
play() { play(volume) {
if (this.howl) { if (this.howl) {
this.playing = true; this.playing = true;
this.howl.volume(volume);
if (this.instance) { if (this.instance) {
this.howl.play(this.instance); this.howl.play(this.instance);
} else { } else {
@ -157,6 +158,12 @@ class MusicInstance extends MusicInstanceInterface {
} }
} }
setVolume(volume) {
if (this.howl) {
this.howl.volume(volume);
}
}
deinitialize() { deinitialize() {
if (this.howl) { if (this.howl) {
this.howl.unload(); this.howl.unload();
@ -204,4 +211,4 @@ export class SoundImplBrowser extends SoundInterface {
deinitialize() { deinitialize() {
return super.deinitialize().then(() => Howler.unload()); return super.deinitialize().then(() => Howler.unload());
} }
} }

View File

@ -61,7 +61,11 @@ export class MusicInstanceInterface {
abstract; abstract;
} }
play() { play(volume) {
abstract;
}
setVolume(volume) {
abstract; abstract;
} }
@ -101,6 +105,9 @@ export class SoundInterface {
this.musicMuted = false; this.musicMuted = false;
this.soundsMuted = false; this.soundsMuted = false;
this.musicVolume = 1.0;
this.soundVolume = 1.0;
} }
/** /**
@ -122,6 +129,8 @@ export class SoundInterface {
this.musicMuted = this.app.settings.getAllSettings().musicMuted; this.musicMuted = this.app.settings.getAllSettings().musicMuted;
this.soundsMuted = this.app.settings.getAllSettings().soundsMuted; this.soundsMuted = this.app.settings.getAllSettings().soundsMuted;
this.musicVolume = this.app.settings.getAllSettings().musicVolume;
this.soundVolume = this.app.settings.getAllSettings().soundsVolume;
if (G_IS_DEV && globalConfig.debug.disableMusic) { if (G_IS_DEV && globalConfig.debug.disableMusic) {
this.musicMuted = true; this.musicMuted = true;
@ -189,7 +198,7 @@ export class SoundInterface {
} }
} else { } else {
if (this.currentMusic) { if (this.currentMusic) {
this.currentMusic.play(); this.currentMusic.play(this.musicVolume);
} }
} }
} }
@ -202,6 +211,41 @@ export class SoundInterface {
this.soundsMuted = muted; this.soundsMuted = muted;
} }
/**
* Returns the music volume
* @returns {number}
*/
getMusicVolume() {
return this.musicVolume;
}
/**
* Returns the sound volume
* @returns {number}
*/
getSoundVolume() {
return this.soundVolume;
}
/**
* Sets the music volume
* @param {number} volume
*/
setMusicVolume(volume) {
this.musicVolume = clamp(volume, 0, 1);;
if (this.currentMusic) {
this.currentMusic.setVolume(this.musicVolume);
}
}
/**
* Sets the sound volume
* @param {number} volume
*/
setSoundVolume(volume) {
this.soundVolume = clamp(volume, 0, 1);
}
/** /**
* Focus change handler, called by the pap * Focus change handler, called by the pap
* @param {boolean} pageIsVisible * @param {boolean} pageIsVisible
@ -211,7 +255,7 @@ export class SoundInterface {
if (this.currentMusic) { if (this.currentMusic) {
if (pageIsVisible) { if (pageIsVisible) {
if (!this.currentMusic.isPlaying() && !this.musicMuted) { if (!this.currentMusic.isPlaying() && !this.musicMuted) {
this.currentMusic.play(); this.currentMusic.play(this.musicVolume);
} }
} else { } else {
this.currentMusic.stop(); this.currentMusic.stop();
@ -230,7 +274,7 @@ export class SoundInterface {
logger.warn("Sound", key, "not found, probably not loaded yet"); logger.warn("Sound", key, "not found, probably not loaded yet");
return; return;
} }
this.sounds[key].play(1.0); this.sounds[key].play(this.soundVolume);
} }
/** /**
@ -253,9 +297,9 @@ export class SoundInterface {
return; return;
} }
let volume = 1.0; let volume = this.soundVolume;
if (!root.camera.isWorldPointOnScreen(worldPosition)) { if (!root.camera.isWorldPointOnScreen(worldPosition)) {
volume = 0.2; volume = this.soundVolume / 5; // In the old implementation this value was fixed to 0.2 => 20% of 1.0
} }
volume *= clamp(root.camera.zoomLevel / 3); volume *= clamp(root.camera.zoomLevel / 3);
this.sounds[key].play(clamp(volume)); this.sounds[key].play(clamp(volume));
@ -277,8 +321,8 @@ export class SoundInterface {
this.currentMusic = music; this.currentMusic = music;
if (music && this.pageIsVisible && !this.musicMuted) { if (music && this.pageIsVisible && !this.musicMuted) {
logger.log("Starting", this.currentMusic.key); logger.log("Starting", this.currentMusic.key);
music.play(); music.play(this.musicVolume);
} }
} }
} }
} }

View File

@ -3,7 +3,7 @@ import { Application } from "../application";
/* typehints:end */ /* typehints:end */
import { ReadWriteProxy } from "../core/read_write_proxy"; import { ReadWriteProxy } from "../core/read_write_proxy";
import { BoolSetting, EnumSetting, BaseSetting } from "./setting_types"; import { BoolSetting, EnumSetting, RangeSetting, BaseSetting } from "./setting_types";
import { createLogger } from "../core/logging"; import { createLogger } from "../core/logging";
import { ExplainedResult } from "../core/explained_result"; import { ExplainedResult } from "../core/explained_result";
import { THEMES, THEME, applyGameTheme } from "../game/theme"; import { THEMES, THEME, applyGameTheme } from "../game/theme";
@ -23,8 +23,7 @@ export const enumCategories = {
advanced: "advanced", advanced: "advanced",
}; };
export const uiScales = [ export const uiScales = [{
{
id: "super_small", id: "super_small",
size: 0.6, size: 0.6,
}, },
@ -46,8 +45,7 @@ export const uiScales = [
}, },
]; ];
export const scrollWheelSensitivities = [ export const scrollWheelSensitivities = [{
{
id: "super_slow", id: "super_slow",
scale: 0.25, scale: 0.25,
}, },
@ -69,8 +67,7 @@ export const scrollWheelSensitivities = [
}, },
]; ];
export const movementSpeeds = [ export const movementSpeeds = [{
{
id: "super_slow", id: "super_slow",
multiplier: 0.25, multiplier: 0.25,
}, },
@ -96,8 +93,7 @@ export const movementSpeeds = [
}, },
]; ];
export const autosaveIntervals = [ export const autosaveIntervals = [{
{
id: "one_minute", id: "one_minute",
seconds: 60, seconds: 60,
}, },
@ -154,9 +150,9 @@ export const allApplicationSettings = [
category: enumCategories.userInterface, category: enumCategories.userInterface,
restartRequired: false, restartRequired: false,
changeCb: changeCb:
/** /**
* @param {Application} app * @param {Application} app
*/ */
(app, id) => app.updateAfterUiScaleChanged(), (app, id) => app.updateAfterUiScaleChanged(),
}), }),
@ -176,6 +172,22 @@ export const allApplicationSettings = [
*/ */
(app, value) => app.sound.setMusicMuted(value) (app, value) => app.sound.setMusicMuted(value)
), ),
new RangeSetting(
"soundVolume",
enumCategories.general,
/**
* @param {Application} app
*/
(app, value) => app.sound.setSoundVolume(value / 100.0)
),
new RangeSetting(
"musicVolume",
enumCategories.general,
/**
* @param {Application} app
*/
(app, value) => app.sound.setMusicVolume(value / 100.0)
),
new BoolSetting( new BoolSetting(
"fullscreen", "fullscreen",
@ -187,8 +199,7 @@ export const allApplicationSettings = [
if (app.platformWrapper.getSupportsFullscreen()) { if (app.platformWrapper.getSupportsFullscreen()) {
app.platformWrapper.setFullscreen(value); app.platformWrapper.setFullscreen(value);
} }
}, }, !IS_DEMO
!IS_DEMO
), ),
new BoolSetting( new BoolSetting(
@ -209,13 +220,13 @@ export const allApplicationSettings = [
category: enumCategories.userInterface, category: enumCategories.userInterface,
restartRequired: false, restartRequired: false,
changeCb: changeCb:
/** /**
* @param {Application} app * @param {Application} app
*/ */
(app, id) => { (app, id) => {
applyGameTheme(id); applyGameTheme(id);
document.documentElement.setAttribute("data-theme", id); document.documentElement.setAttribute("data-theme", id);
}, },
enabled: !IS_DEMO, enabled: !IS_DEMO,
}), }),
@ -226,9 +237,9 @@ export const allApplicationSettings = [
category: enumCategories.advanced, category: enumCategories.advanced,
restartRequired: false, restartRequired: false,
changeCb: changeCb:
/** /**
* @param {Application} app * @param {Application} app
*/ */
(app, id) => null, (app, id) => null,
}), }),
@ -239,9 +250,9 @@ export const allApplicationSettings = [
category: enumCategories.advanced, category: enumCategories.advanced,
restartRequired: false, restartRequired: false,
changeCb: changeCb:
/** /**
* @param {Application} app * @param {Application} app
*/ */
(app, id) => app.updateAfterUiScaleChanged(), (app, id) => app.updateAfterUiScaleChanged(),
}), }),
@ -289,6 +300,9 @@ class SettingsStorage {
this.soundsMuted = false; this.soundsMuted = false;
this.musicMuted = false; this.musicMuted = false;
this.soundVolume = 1.0;
this.musicVolume = 1.0;
this.theme = "light"; this.theme = "light";
this.refreshRate = "60"; this.refreshRate = "60";
this.scrollWheelSensitivity = "regular"; this.scrollWheelSensitivity = "regular";
@ -336,7 +350,7 @@ export class ApplicationSettings extends ReadWriteProxy {
} }
}) })
.then(() => this.writeAsync()); .then(() => this.writeAsync());
} }
save() { save() {
@ -437,7 +451,7 @@ export class ApplicationSettings extends ReadWriteProxy {
/** /**
* @param {string} key * @param {string} key
* @param {string|boolean} value * @param {string|boolean|number} value
*/ */
updateSetting(key, value) { updateSetting(key, value) {
for (let i = 0; i < allApplicationSettings.length; ++i) { for (let i = 0; i < allApplicationSettings.length; ++i) {
@ -472,12 +486,12 @@ export class ApplicationSettings extends ReadWriteProxy {
* @param {string} id * @param {string} id
*/ */
resetKeybindingOverride(id) { resetKeybindingOverride(id) {
delete this.getAllSettings().keybindingOverrides[id]; delete this.getAllSettings().keybindingOverrides[id];
return this.writeAsync(); return this.writeAsync();
} }
/** /**
* Resets all keybinding overrides * Resets all keybinding overrides
*/ */
resetKeybindingOverrides() { resetKeybindingOverrides() {
this.getAllSettings().keybindingOverrides = {}; this.getAllSettings().keybindingOverrides = {};
return this.writeAsync(); return this.writeAsync();
@ -511,7 +525,7 @@ export class ApplicationSettings extends ReadWriteProxy {
} }
getCurrentVersion() { getCurrentVersion() {
return 23; return 24;
} }
/** @param {{settings: SettingsStorage, version: number}} data */ /** @param {{settings: SettingsStorage, version: number}} data */
@ -614,6 +628,12 @@ export class ApplicationSettings extends ReadWriteProxy {
data.version = 23; data.version = 23;
} }
if (data.version < 24) {
data.settings.musicVolume = 1.0;
data.settings.soundVolume = 1.0;
data.version = 24;
}
return ExplainedResult.good(); return ExplainedResult.good();
} }
} }

View File

@ -85,8 +85,7 @@ export class BaseSetting {
export class EnumSetting extends BaseSetting { export class EnumSetting extends BaseSetting {
constructor( constructor(
id, id, {
{
options, options,
valueGetter, valueGetter,
textGetter, textGetter,
@ -111,7 +110,7 @@ export class EnumSetting extends BaseSetting {
} }
getHtml() { getHtml() {
return ` return `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}"> <div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}">
${this.enabled ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`} ${this.enabled ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`}
<div class="row"> <div class="row">
@ -220,3 +219,62 @@ export class BoolSetting extends BaseSetting {
return typeof value === "boolean"; return typeof value === "boolean";
} }
} }
export class RangeSetting extends BaseSetting {
constructor(id, category, changeCb = null, enabled = true, defaultValue = 100, minValue = 0, maxValue = 100, stepSize = 1) {
super(id, category, changeCb, enabled);
this.defaultValue = defaultValue;
this.minValue = minValue;
this.maxValue = maxValue;
this.stepSize = stepSize;
}
getHtml() {
return `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}">
${this.enabled ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`}
<div class="row">
<label>${T.settings.labels[this.id].title}</label>
<div class="value range" data-setting="${this.id}">
<label class="range-label">${this.defaultValue}</label>
<input class="range-input" type="range" value="${this.defaultValue}" min="${this.minValue}" max="${this.maxValue}" step="${this.stepSize}">
</div>
</div>
<div class="desc">
${T.settings.labels[this.id].description}
</div>
</div>`;
}
bind(app, element, dialogs) {
this.app = app;
this.element = element;
this.dialogs = dialogs;
this.element.querySelector(".range-input").addEventListener("input", () => {
this.modify();
});
}
syncValueToElement() {
const value = this.app.settings.getSetting(this.id);
this.element.querySelector(".range-input").value = value;
this.element.querySelector(".range-label").innerText = value;
}
modify() {
const newValue = Number(this.element.querySelector(".range-input").value);
this.app.settings.updateSetting(this.id, newValue);
this.syncValueToElement();
if (this.changeCb) {
this.changeCb(this.app, newValue);
}
}
validate(value) {
return typeof value === "number";
}
}

View File

@ -732,6 +732,16 @@ settings:
description: >- description: >-
Bei der Aktivierung wird die Musik stummgeschaltet. Bei der Aktivierung wird die Musik stummgeschaltet.
soundVolume:
title: Geräuschlautstärke
description: >-
Ändert die Lautstärke von Geräuschen.
musicVolume:
title: Musiklautstärke
description: >-
Ändert die Lautstärke der Musik.
theme: theme:
title: Farbmodus title: Farbmodus
description: >- description: >-

View File

@ -801,6 +801,16 @@ settings:
description: >- description: >-
If enabled, mutes all music. If enabled, mutes all music.
soundVolume:
title: Sound Volume
description: >-
Set the volume for sound effects
musicVolume:
title: Music Volume
description: >-
Set the volume for music
theme: theme:
title: Game theme title: Game theme
description: >- description: >-