diff --git a/CMakeLists.txt b/CMakeLists.txt index 04d36ac..adcc550 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16.0) project(pipedal - VERSION 1.1.29 + VERSION 1.1.30 DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi" HOMEPAGE_URL "https://rerdavies.github.io/pipedal" ) diff --git a/debian/control b/debian/control index 2b872ef..f1651a7 100644 --- a/debian/control +++ b/debian/control @@ -9,6 +9,6 @@ Package: pipedal Pre-Depends: hostapd;authbind;dnsmasq Priority: optional Section: sound -Version: 1.1.29 +Version: 1.1.30 Installed-Size: 15147 diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index ec1e9d3..3af69fd 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -1,4 +1,8 @@ # Release Notes +## PiPedal 1.1.30 + +- Use system preferences for dark mode when connecting from Android app. +- ## PiPedal 1.1.28 diff --git a/docs/index.md b/docs/index.md index e44b923..fdefbdc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,7 +7,7 @@ To download PiPedal, click [here](download.md). -> NEW version 1.1.29 release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details. +> NEW version 1.1.30 release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details. Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet. diff --git a/react/package.json b/react/package.json index 32b1da0..477237d 100644 --- a/react/package.json +++ b/react/package.json @@ -58,6 +58,7 @@ }, "devDependencies": { "@types/react-virtualized-auto-sizer": "^1.0.1", - "@types/react-window": "^1.8.5" + "@types/react-window": "^1.8.5", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2" } } diff --git a/react/public/index.html b/react/public/index.html index 87fec91..0e138f2 100644 --- a/react/public/index.html +++ b/react/public/index.html @@ -40,22 +40,52 @@ } - - - -
- - + + \ No newline at end of file diff --git a/react/src/App.tsx b/react/src/App.tsx index 9efc4dd..f0d5078 100644 --- a/react/src/App.tsx +++ b/react/src/App.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { ThemeProvider, createTheme, StyledEngineProvider, Theme } from '@mui/material/styles'; import AppThemed from "./AppThemed"; -import isDarkMode from './DarkMode'; +import {isDarkMode} from './DarkMode'; declare module '@mui/material/styles' { interface Theme { diff --git a/react/src/AppThemed.tsx b/react/src/AppThemed.tsx index aeb2ffa..a3490ba 100644 --- a/react/src/AppThemed.tsx +++ b/react/src/AppThemed.tsx @@ -60,7 +60,7 @@ import { BankIndex, BankIndexEntry } from './Banks'; import RenameDialog from './RenameDialog'; import JackStatusView from './JackStatusView'; import { Theme } from '@mui/material/styles'; -import isDarkMode from './DarkMode'; +import {isDarkMode} from './DarkMode'; import {ReactComponent as RenameOutlineIcon} from './svg/drive_file_rename_outline_black_24dp.svg'; import {ReactComponent as SaveBankAsIcon} from './svg/ic_save_bank_as.svg'; diff --git a/react/src/DarkMode.tsx b/react/src/DarkMode.tsx index 4bf6189..1c64522 100644 --- a/react/src/DarkMode.tsx +++ b/react/src/DarkMode.tsx @@ -17,12 +17,58 @@ // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +export enum ColorTheme { + Light, + Dark, + System +}; -export default function isDarkMode(): boolean { - let value = localStorage.getItem("darkMode"); - return value === "true"; + + +export function getColorScheme(): ColorTheme { + const androidHosted = !!((window as any).AndroidHost); + + switch (localStorage.getItem('colorScheme')) { + case null: + default: + if (androidHosted) { + return ColorTheme.System; + } else { + return ColorTheme.Light; + } + case "Light": + return ColorTheme.Light; + case "Dark": + return ColorTheme.Dark; + case "System": + return ColorTheme.System; + } } +export function setColorScheme(value: ColorTheme): void { + var storageValue; + switch (value) { + default: + case ColorTheme.Light: + storageValue = "Light"; + break; + case ColorTheme.Dark: + storageValue = "Dark"; + break; -export function setDarkMode(value: boolean): void { - localStorage.setItem("darkMode",value? "true": "false"); + case ColorTheme.System: + storageValue = "System"; + break; + } + localStorage.setItem("colorScheme", storageValue); } + +export function isDarkMode(): boolean { + var colorTheme = getColorScheme(); + if (colorTheme === ColorTheme.System) { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + return true; + } + } + return colorTheme === ColorTheme.Dark; +} + diff --git a/react/src/DraggableGrid.tsx b/react/src/DraggableGrid.tsx index 0a1e967..dae87cb 100644 --- a/react/src/DraggableGrid.tsx +++ b/react/src/DraggableGrid.tsx @@ -21,7 +21,7 @@ import { Theme } from '@mui/material/styles'; import createStyles from '@mui/styles/createStyles'; import { Property } from "csstype"; import { nullCast} from './Utility' -import isDarkMode from './DarkMode'; +import {isDarkMode} from './DarkMode'; const SELECT_SCALE = 1.0; diff --git a/react/src/FilePropertyControl.tsx b/react/src/FilePropertyControl.tsx index 1e29b65..00e66ae 100644 --- a/react/src/FilePropertyControl.tsx +++ b/react/src/FilePropertyControl.tsx @@ -33,8 +33,7 @@ import { PiPedalModel, PiPedalModelFactory, ListenHandle} from './PiPedalModel'; import ButtonBase from '@mui/material/ButtonBase' import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; import {PedalboardItem} from './Pedalboard'; -import isDarkMode from './DarkMode'; - +import {isDarkMode} from './DarkMode'; export const StandardItemSize = { width: 80, height: 140 } diff --git a/react/src/GxTunerControl.tsx b/react/src/GxTunerControl.tsx index e222533..606812f 100644 --- a/react/src/GxTunerControl.tsx +++ b/react/src/GxTunerControl.tsx @@ -24,8 +24,7 @@ import createStyles from '@mui/styles/createStyles'; import withStyles from '@mui/styles/withStyles'; import { MonitorPortHandle, PiPedalModel, State, PiPedalModelFactory } from "./PiPedalModel"; import SvgPathBuilder from './SvgPathBuilder' -import isDarkMode from './DarkMode'; - +import {isDarkMode} from './DarkMode'; //const char* model[] = {"12-TET","19-TET","24-TET", "31-TET", "53-TET"}; // set_adjustment(ui->widget[2]->adj,440.0, 440.0, 427.0, 453.0, 0.1, CL_CONTINUOS); diff --git a/react/src/JackHostStatus.tsx b/react/src/JackHostStatus.tsx index dc831f0..adcde7e 100644 --- a/react/src/JackHostStatus.tsx +++ b/react/src/JackHostStatus.tsx @@ -19,8 +19,7 @@ import React from 'react'; import Typography from '@mui/material/Typography'; -import isDarkMode from './DarkMode'; - +import {isDarkMode} from './DarkMode'; const RED_COLOR = isDarkMode()? "#F88":"#C00"; const GREEN_COLOR = isDarkMode()? "rgba(255,255,255,0.7)": "#666"; diff --git a/react/src/MainPage.tsx b/react/src/MainPage.tsx index 6dd2b4c..790d536 100644 --- a/react/src/MainPage.tsx +++ b/react/src/MainPage.tsx @@ -47,8 +47,7 @@ import MidiBindingsDialog from './MidiBindingsDialog'; import PluginPresetSelector from './PluginPresetSelector'; import {ReactComponent as OldDeleteIcon} from "./svg/old_delete_outline_24dp.svg"; import {ReactComponent as MidiIcon} from "./svg/ic_midi.svg"; -import isDarkMode from './DarkMode'; - +import {isDarkMode} from './DarkMode'; const SPLIT_CONTROLBAR_THRESHHOLD = 650; diff --git a/react/src/PedalboardView.tsx b/react/src/PedalboardView.tsx index 212f3f4..6ff6022 100644 --- a/react/src/PedalboardView.tsx +++ b/react/src/PedalboardView.tsx @@ -33,8 +33,7 @@ import Draggable from './Draggable' import Rect from './Rect'; import {PiPedalStateError} from './PiPedalError'; import Utility from './Utility'; -import isDarkMode from './DarkMode'; - +import {isDarkMode} from './DarkMode'; import { Pedalboard, PedalboardItem, PedalboardSplitItem, SplitType } from './Pedalboard'; diff --git a/react/src/PiPedalModel.tsx b/react/src/PiPedalModel.tsx index c25b27d..83bc538 100644 --- a/react/src/PiPedalModel.tsx +++ b/react/src/PiPedalModel.tsx @@ -38,12 +38,8 @@ import GovernorSettings from './GovernorSettings'; import WifiChannel from './WifiChannel'; import AlsaDeviceInfo from './AlsaDeviceInfo'; import { AndroidHostInterface, FakeAndroidHost } from './AndroidHost'; -import isDarkMode, {setDarkMode} from './DarkMode'; +import {ColorTheme, getColorScheme,setColorScheme} from './DarkMode'; -export enum ColorTheme { - Light, - Dark -}; export enum State { Loading, @@ -2546,13 +2542,14 @@ export class PiPedalModel //implements PiPedalModel } getTheme(): ColorTheme { - return isDarkMode() ? ColorTheme.Dark: ColorTheme.Light; + return getColorScheme(); } setTheme(value: ColorTheme) { + if (this.getTheme() !== value) { - setDarkMode(value === ColorTheme.Dark); + setColorScheme(value); this.reloadPage(); } } @@ -2562,7 +2559,7 @@ export class PiPedalModel //implements PiPedalModel reloadPage() { this.reloadRequested = true; // eslint-disable-next-line no-restricted-globals - location.reload(); + window.location.reload(); } diff --git a/react/src/PluginOutputControl.tsx b/react/src/PluginOutputControl.tsx index 97baaf8..a9aa469 100644 --- a/react/src/PluginOutputControl.tsx +++ b/react/src/PluginOutputControl.tsx @@ -25,8 +25,7 @@ import withStyles from '@mui/styles/withStyles'; import { UiControl } from './Lv2Plugin'; import Typography from '@mui/material/Typography'; import { PiPedalModel, PiPedalModelFactory, MonitorPortHandle,State } from './PiPedalModel'; -import isDarkMode from './DarkMode'; - +import {isDarkMode} from './DarkMode'; diff --git a/react/src/PresetDialog.tsx b/react/src/PresetDialog.tsx index 3e9a833..76a22e8 100644 --- a/react/src/PresetDialog.tsx +++ b/react/src/PresetDialog.tsx @@ -18,7 +18,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import React, { SyntheticEvent,Component } from 'react'; -import isDarkMode from './DarkMode'; +import {isDarkMode} from './DarkMode'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import { PiPedalModel, PiPedalModelFactory, PresetIndexEntry, PresetIndex } from './PiPedalModel'; diff --git a/react/src/PresetSelector.tsx b/react/src/PresetSelector.tsx index 8fca8ae..b9776a2 100644 --- a/react/src/PresetSelector.tsx +++ b/react/src/PresetSelector.tsx @@ -34,8 +34,7 @@ import Divider from '@mui/material/Divider'; import RenameDialog from './RenameDialog' import Select from '@mui/material/Select'; import UploadPresetDialog from './UploadPresetDialog'; -import isDarkMode from './DarkMode'; - +import {isDarkMode} from './DarkMode'; interface PresetSelectorProps extends WithStyles { diff --git a/react/src/SelectThemeDialog.tsx b/react/src/SelectThemeDialog.tsx index 92df59f..83e3074 100644 --- a/react/src/SelectThemeDialog.tsx +++ b/react/src/SelectThemeDialog.tsx @@ -29,7 +29,7 @@ import FormControl from '@mui/material/FormControl'; import RadioGroup from '@mui/material/RadioGroup'; import Radio from '@mui/material/Radio'; -import {ColorTheme} from './PiPedalModel'; +import {ColorTheme} from './DarkMode'; @@ -45,7 +45,14 @@ function SelectThemesDialog(props: SelectThemesDialogProps) { const { onClose, defaultTheme, open,onOk } = props; const [ selectedTheme, setSelectedTheme ] = useState(defaultTheme); const handleChange = (event: React.ChangeEvent) => { - let value = ((event.target as HTMLInputElement).value) === '0' ? ColorTheme.Light: ColorTheme.Dark; + let value = ColorTheme.Light; + if ((event.target as HTMLInputElement).value === '1') + { + value = ColorTheme.Dark; + } else if ((event.target as HTMLInputElement).value === '2') + { + value = ColorTheme.System; + } setSelectedTheme(value); }; const handleClose = (): void => { @@ -67,6 +74,7 @@ function SelectThemesDialog(props: SelectThemesDialogProps) { > } label="Light" /> } label="Dark" /> + } label="Use system setting" /> diff --git a/react/src/SettingsDialog.tsx b/react/src/SettingsDialog.tsx index ef31072..8308aa3 100644 --- a/react/src/SettingsDialog.tsx +++ b/react/src/SettingsDialog.tsx @@ -23,7 +23,8 @@ import OkCancelDialog from './OkCancelDialog'; import ListSelectDialog from './ListSelectDialog'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; -import { PiPedalModel, PiPedalModelFactory, State, ColorTheme } from './PiPedalModel'; +import { PiPedalModel, PiPedalModelFactory, State } from './PiPedalModel'; +import {ColorTheme} from './DarkMode'; import ButtonBase from "@mui/material/ButtonBase"; import AppBar from '@mui/material/AppBar'; import Button from '@mui/material/Button'; @@ -749,7 +750,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })( Color Theme - { this.model.getTheme() === ColorTheme.Dark ? "Dark" :"Light"} + { this.model.getTheme() === ColorTheme.Dark ? "Dark" : + (this.model.getTheme() === ColorTheme.Light ? "Light": "System")} diff --git a/react/src/TemporaryDrawer.tsx b/react/src/TemporaryDrawer.tsx index 9e82237..ffcca26 100644 --- a/react/src/TemporaryDrawer.tsx +++ b/react/src/TemporaryDrawer.tsx @@ -26,8 +26,7 @@ import IconButton from '@mui/material/Toolbar'; import Drawer from '@mui/material/Drawer'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import { Theme } from '@mui/material/styles'; -import isDarkMode from './DarkMode'; - +import {isDarkMode} from './DarkMode'; const drawerStyles = (theme: Theme) => { return createStyles({ diff --git a/src/PiPedalUI.hpp b/src/PiPedalUI.hpp index dfafdcb..ce6c13f 100644 --- a/src/PiPedalUI.hpp +++ b/src/PiPedalUI.hpp @@ -107,7 +107,7 @@ namespace pipedal { class UiFileProperty { private: std::string label_; - std::int64_t index_ = -1; + std::int32_t index_ = -1; std::string directory_; std::vector fileTypes_; std::string patchProperty_; @@ -120,7 +120,7 @@ namespace pipedal { const std::string &label() const { return label_; } - int64_t index() const { return index_; } + int32_t index() const { return index_; } const std::string &directory() const { return directory_; } const std::string&portGroup() const { return portGroup_; } @@ -137,7 +137,7 @@ namespace pipedal { class UiFrequencyPlot { private: std::string patchProperty_; - std::int64_t index_ = -1; + std::int32_t index_ = -1; std::string portGroup_; float xLeft_ = 100; float xRight_ = 22000; @@ -152,11 +152,11 @@ namespace pipedal { const std::filesystem::path&resourcePath); const std::string &patchProperty() const { return patchProperty_; } - int64_t index() const { return index_; } + int32_t index() const { return index_; } const std::string&portGroup() const { return portGroup_; } float xLeft() const { return xLeft_; } float xRight() const { return xRight_; } - float xLog() const { return xLog_; } + bool xLog() const { return xLog_; } float yTop() const { return yTop_; } float yBottom() const { return yBottom_; } float width() const { return width_; } diff --git a/src/PluginHost.cpp b/src/PluginHost.cpp index 757e49a..606b9cb 100644 --- a/src/PluginHost.cpp +++ b/src/PluginHost.cpp @@ -105,6 +105,7 @@ void PluginHost::SetConfiguration(const PiPedalConfiguration &configuration) void PluginHost::LilvUris::Initialize(LilvWorld *pWorld) { + isA = lilv_new_uri(pWorld, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); rdfs__Comment = lilv_new_uri(pWorld, PluginHost::RDFS__comment); rdfs__range = lilv_new_uri(pWorld, PluginHost::RDFS__range); port_logarithmic = lilv_new_uri(pWorld, LV2_PORT_PROPS__logarithmic); @@ -591,7 +592,7 @@ std::shared_ptr Lv2PluginInfo::FindWritablePathProperties(PluginHost AutoLilvNode propertyUri = lilv_nodes_get(patchWritables, iNode); if (propertyUri) { - // isA lv2:Parameter? + // a lv2:Parameter? if (lilv_world_ask(pWorld, propertyUri, lv2Host->lilvUris.isA, lv2Host->lilvUris.lv2core__Parameter)) { // rfs:range atom:Path? diff --git a/src/json.cpp b/src/json.cpp index d945199..2183aa1 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -634,6 +634,7 @@ void json_reader::throw_format_error(const char*error) } + // void json_writer::write(const json_variant &value) // { // ((JsonSerializable *)&value)->write_json(*this); diff --git a/src/main.cpp b/src/main.cpp index 13aeb02..2f9b44e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -700,12 +700,9 @@ int main(int argc, char *argv[]) { // wait up to 15 seconds for the midi device to come online. auto devices = model.GetAlsaDevices(); - bool firstMessage = true; bool found = false; if (!HasAlsaDevice(devices, serverSettings.GetAlsaInputDevice())) { - if (firstMessage) Lv2Log::info(SS("Waiting for ALSA device " << serverSettings.GetAlsaInputDevice() << " to come online...")); - firstMessage = false; for (int i = 0; i < 5; ++i) { sleep(3); @@ -717,10 +714,11 @@ int main(int argc, char *argv[]) } if (g_SigBreak) exit(1); - if (systemd) + if (!systemd) { break; } + Lv2Log::info(SS("Waiting for ALSA device " << serverSettings.GetAlsaInputDevice() << " to come online...")); } if (found) {