diff --git a/Documents/discoDSP/OB-Xd/Banks/023 - Luke's Soundhouse 80s & Synthwave.FXB b/Documents/discoDSP/OB-Xd/Banks/023 - Luke's Soundhouse 80s & Synthwave.FXB
new file mode 100644
index 0000000..f398ebc
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Banks/023 - Luke's Soundhouse 80s & Synthwave.FXB differ
diff --git a/Documents/discoDSP/OB-Xd/MIDI CC.txt b/Documents/discoDSP/OB-Xd/MIDI CC.txt
deleted file mode 100644
index e06b7a6..0000000
--- a/Documents/discoDSP/OB-Xd/MIDI CC.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-OB-Xd default MIDI CC controller table.
-Modify by clicking LEARN button, moving a GUI element and then sending MIDI CC data.
-All values can be reset using CLEAN button.
-
-CC# CONTROL
-
-21 ASPLAYEDALLOCATION
-105 BANDPASS
-75 BENDLFORATE
-34 BENDOSC2
-118 BENDRANGE
-62 BRIGHTNESS
-74 CUTOFF
-111 ECONOMY_MODE
-115 ENV_PITCH_BOTH
-108 ENVDER
-107 ENVELOPE_AMT
-63 ENVPITCH
-38 FATK
-39 FDEC
-116 FENV_INVERT
-18 FILTER_WARM
-109 FILTERDER
-103 FLT_KF
-106 FOURPOLE
-41 FREL
-40 FSUS
-73 LATK
-36 LDEC
-35 LEGATOMODE
-118 LEVEL_DIF
-22 LFO1AMT
-25 LFO2AMT
-49 LFOFILTER
-19 LFOFREQ
-47 LFOOSC1
-48 LFOOSC2
-50 LFOPW1
-51 LFOPW2
-46 LFOSHWAVE
-44 LFOSINWAVE
-45 LFOSQUAREWAVE
-72 LREL
-37 LSUS
-104 MULTIMODE
-102 NOISEMIX
-17 OCTAVE
-77 OSC1MIX
-54 OSC1P
-58 OSC1Pul
-57 OSC1Saw
-43 OSC2_DET
-52 OSC2HS
-78 OSC2MIX
-55 OSC2P
-60 OSC2Pul
-59 OSC2Saw
-56 OSCQuantize
-81 PAN1
-82 PAN2
-83 PAN3
-84 PAN4
-85 PAN5
-86 PAN6
-87 PAN7
-88 PAN8
-110 PORTADER
-23 PORTAMENTO
-61 PW
-113 PW_ENV
-114 PW_ENV_BOTH
-117 PW_OSC2_OFS
-42 RESONANCE
-119 SELF_OSC_PUSH
-33 TUNE
-24 UDET
-16 UNISON
-20 VAMPENV
-76 VFLTENV
-15 VOICE_COUNT
-71 VOLUME
-53 XMOD
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Arturia MicroFreak.xml b/Documents/discoDSP/OB-Xd/MIDI/Arturia MicroFreak.xml
new file mode 100755
index 0000000..a67045c
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Arturia MicroFreak.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Config.xml b/Documents/discoDSP/OB-Xd/MIDI/Config.xml
new file mode 100644
index 0000000..6352e53
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Config.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Custom.xml b/Documents/discoDSP/OB-Xd/MIDI/Custom.xml
new file mode 100644
index 0000000..a877aef
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Custom.xml
@@ -0,0 +1,22 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Dave Smith Instruments OB-6.xml b/Documents/discoDSP/OB-Xd/MIDI/Dave Smith Instruments OB-6.xml
new file mode 100755
index 0000000..8fee0a9
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Dave Smith Instruments OB-6.xml
@@ -0,0 +1,22 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Default.xml b/Documents/discoDSP/OB-Xd/MIDI/Default.xml
new file mode 100644
index 0000000..cf5b58c
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Default.xml
@@ -0,0 +1,22 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Elektron Analog Four MKII.xml b/Documents/discoDSP/OB-Xd/MIDI/Elektron Analog Four MKII.xml
new file mode 100755
index 0000000..818881d
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Elektron Analog Four MKII.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Elektron Digitakt.xml b/Documents/discoDSP/OB-Xd/MIDI/Elektron Digitakt.xml
new file mode 100755
index 0000000..a250382
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Elektron Digitakt.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Elektron Digitone.xml b/Documents/discoDSP/OB-Xd/MIDI/Elektron Digitone.xml
new file mode 100755
index 0000000..068ea3c
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Elektron Digitone.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/IK Multimedia Uno Synth.xml b/Documents/discoDSP/OB-Xd/MIDI/IK Multimedia Uno Synth.xml
new file mode 100755
index 0000000..74107ed
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/IK Multimedia Uno Synth.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/KORG MS2000.xml b/Documents/discoDSP/OB-Xd/MIDI/KORG MS2000.xml
new file mode 100755
index 0000000..4ef8e62
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/KORG MS2000.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/KORG micro KORG.xml b/Documents/discoDSP/OB-Xd/MIDI/KORG micro KORG.xml
new file mode 100755
index 0000000..5b67e16
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/KORG micro KORG.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/KORG minilogue xd.xml b/Documents/discoDSP/OB-Xd/MIDI/KORG minilogue xd.xml
new file mode 100755
index 0000000..9ba2792
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/KORG minilogue xd.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/KORG minilogue.xml b/Documents/discoDSP/OB-Xd/MIDI/KORG minilogue.xml
new file mode 100755
index 0000000..f5d6c1f
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/KORG minilogue.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/KORG monologue.xml b/Documents/discoDSP/OB-Xd/MIDI/KORG monologue.xml
new file mode 100755
index 0000000..9ba2792
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/KORG monologue.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Modal Craft.xml b/Documents/discoDSP/OB-Xd/MIDI/Modal Craft.xml
new file mode 100755
index 0000000..4a71a23
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Modal Craft.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Modal Skulpt.xml b/Documents/discoDSP/OB-Xd/MIDI/Modal Skulpt.xml
new file mode 100755
index 0000000..7f73ad0
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Modal Skulpt.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Moog Minitaur.xml b/Documents/discoDSP/OB-Xd/MIDI/Moog Minitaur.xml
new file mode 100755
index 0000000..eaa9f58
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Moog Minitaur.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Moog Sirin.xml b/Documents/discoDSP/OB-Xd/MIDI/Moog Sirin.xml
new file mode 100755
index 0000000..0c0239a
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Moog Sirin.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Moog Sub 37.xml b/Documents/discoDSP/OB-Xd/MIDI/Moog Sub 37.xml
new file mode 100755
index 0000000..8b90e7a
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Moog Sub 37.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Moog Sub Phatty.xml b/Documents/discoDSP/OB-Xd/MIDI/Moog Sub Phatty.xml
new file mode 100755
index 0000000..cf5b58c
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Moog Sub Phatty.xml
@@ -0,0 +1,22 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Mutable Instruments Shruthi.xml b/Documents/discoDSP/OB-Xd/MIDI/Mutable Instruments Shruthi.xml
new file mode 100755
index 0000000..af14437
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Mutable Instruments Shruthi.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Novation Circuit.xml b/Documents/discoDSP/OB-Xd/MIDI/Novation Circuit.xml
new file mode 100755
index 0000000..01775f8
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Novation Circuit.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Roland JD-XA.xml b/Documents/discoDSP/OB-Xd/MIDI/Roland JD-XA.xml
new file mode 100755
index 0000000..b078326
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Roland JD-XA.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Roland JD-Xi.xml b/Documents/discoDSP/OB-Xd/MIDI/Roland JD-Xi.xml
new file mode 100755
index 0000000..c03b49d
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Roland JD-Xi.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Roland JP-08.xml b/Documents/discoDSP/OB-Xd/MIDI/Roland JP-08.xml
new file mode 100755
index 0000000..c698e7b
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Roland JP-08.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Roland JU-06.xml b/Documents/discoDSP/OB-Xd/MIDI/Roland JU-06.xml
new file mode 100755
index 0000000..c698e7b
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Roland JU-06.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Roland JX-03.xml b/Documents/discoDSP/OB-Xd/MIDI/Roland JX-03.xml
new file mode 100755
index 0000000..8ee8fd6
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Roland JX-03.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Roland SE-02.xml b/Documents/discoDSP/OB-Xd/MIDI/Roland SE-02.xml
new file mode 100755
index 0000000..c4c8145
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Roland SE-02.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Roland SH-01A.xml b/Documents/discoDSP/OB-Xd/MIDI/Roland SH-01A.xml
new file mode 100755
index 0000000..0241aab
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Roland SH-01A.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Roland System-8.xml b/Documents/discoDSP/OB-Xd/MIDI/Roland System-8.xml
new file mode 100755
index 0000000..b50b8df
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Roland System-8.xml
@@ -0,0 +1,18 @@
+
+
+
\ No newline at end of file
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Studiologic Sledge.xml b/Documents/discoDSP/OB-Xd/MIDI/Studiologic Sledge.xml
new file mode 100755
index 0000000..ebdf0c4
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Studiologic Sledge.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Tasty Chips GR-1.xml b/Documents/discoDSP/OB-Xd/MIDI/Tasty Chips GR-1.xml
new file mode 100755
index 0000000..53facf7
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Tasty Chips GR-1.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/Waldorf Blofeld.xml b/Documents/discoDSP/OB-Xd/MIDI/Waldorf Blofeld.xml
new file mode 100755
index 0000000..d7b1bd6
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/Waldorf Blofeld.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/MIDI/freds-lab buzzzy.xml b/Documents/discoDSP/OB-Xd/MIDI/freds-lab buzzzy.xml
new file mode 100755
index 0000000..0b71514
--- /dev/null
+++ b/Documents/discoDSP/OB-Xd/MIDI/freds-lab buzzzy.xml
@@ -0,0 +1,78 @@
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/OB-Xd Manual.pdf b/Documents/discoDSP/OB-Xd/OB-Xd Manual.pdf
new file mode 100644
index 0000000..d1910ba
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/OB-Xd Manual.pdf differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button.png
old mode 100755
new mode 100644
index e410d33..1c36523
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button@2x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button@2x.png
old mode 100755
new mode 100644
index d3f0661..f206785
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button@4x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button@4x.png
new file mode 100644
index 0000000..166dc44
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/button@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/coords.xml b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/coords.xml
old mode 100755
new mode 100644
index 243851d..61738dc
--- a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/coords.xml
+++ b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/coords.xml
@@ -1,116 +1,116 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob.png
old mode 100755
new mode 100644
index 7e54bcb..bef0a4d
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob@2x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob@2x.png
old mode 100755
new mode 100644
index 846531e..816c9ef
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob@4x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob@4x.png
new file mode 100644
index 0000000..54e588c
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/knob@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato.png
old mode 100755
new mode 100644
index 7590f32..b54c434
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato@2x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato@2x.png
old mode 100755
new mode 100644
index d63887e..443b405
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato@4x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato@4x.png
new file mode 100644
index 0000000..d479cb2
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/legato@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main.png
old mode 100755
new mode 100644
index f0f0b0c..60f2860
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main@2x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main@2x.png
old mode 100755
new mode 100644
index cc3d8bc..2cf130c
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main@4x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main@4x.png
new file mode 100644
index 0000000..d4b0c98
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/main@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu.png
old mode 100755
new mode 100644
index dc19076..85ab654
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu@2x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu@2x.png
old mode 100755
new mode 100644
index 8771d76..8c7efc4
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu@4x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu@4x.png
new file mode 100644
index 0000000..3ea7cb5
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/menu@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices.png
old mode 100755
new mode 100644
index 9738939..6ac6c3d
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices@2x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices@2x.png
old mode 100755
new mode 100644
index 3cde5f3..fea43cc
Binary files a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices@4x.png b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices@4x.png
new file mode 100644
index 0000000..1784628
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Ilkka Rosma Dark/voices@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button.png
old mode 100755
new mode 100644
index 04cf119..0e2f7b6
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button@2x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button@2x.png
old mode 100755
new mode 100644
index 858511a..79ccb01
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button@4x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button@4x.png
new file mode 100644
index 0000000..6a93d6c
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/button@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/coords.xml b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/coords.xml
index 044a18b..d755bc3 100755
--- a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/coords.xml
+++ b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/coords.xml
@@ -5,15 +5,15 @@
-
-
-
+
+
+
-
+
-
+
@@ -33,30 +33,30 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
@@ -65,21 +65,21 @@
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
@@ -101,17 +101,17 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob.png
index 2525342..ad97bcc 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob@2x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob@2x.png
index 8f0d205..6b6d0ac 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob@4x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob@4x.png
new file mode 100644
index 0000000..51aed75
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/knob@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato.png
old mode 100755
new mode 100644
index 34e9a9c..2f4e6fb
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato@2x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato@4x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato@4x.png
new file mode 100644
index 0000000..f6da12d
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/legato@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main.png
old mode 100755
new mode 100644
index eb266eb..7171cff
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main@2x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main@2x.png
old mode 100755
new mode 100644
index ca00faf..5bd922e
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main@2x.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main@4x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main@4x.png
new file mode 100644
index 0000000..68f121e
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/main@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu.png
old mode 100755
new mode 100644
index 2b5e0b6..e3abcde
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu@2x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu@4x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu@4x.png
new file mode 100644
index 0000000..2dc9647
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/menu@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices.png
old mode 100755
new mode 100644
index 2e4d0ce..ca9ef6d
Binary files a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices.png and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices@2x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices@4x.png b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices@4x.png
new file mode 100644
index 0000000..07513f7
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/Rin Elyran Classic SEM/voices@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button.png
index fa95a0a..dd8a52f 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button@2x.png
old mode 100755
new mode 100644
index 5082889..d1fa7f4
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button@2x.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button@4x.png
new file mode 100644
index 0000000..b345dac
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/button@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/coords.xml b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/coords.xml
index 94e3016..7d79607 100755
--- a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/coords.xml
+++ b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/coords.xml
@@ -5,32 +5,32 @@
-
+
-
-
+
+
-
+
-
+
-
-
-
+
+
+
@@ -45,9 +45,9 @@
-
-
-
+
+
+
@@ -58,22 +58,22 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
@@ -83,34 +83,34 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob.png
index 483d151..f22e3eb 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x.png
index 0dd5c06..0093274 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x_old.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x_old.png
deleted file mode 100755
index f9fb07a..0000000
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@2x_old.png and /dev/null differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@4x.png
new file mode 100644
index 0000000..4b7e209
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/knob@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato.png
index 8615d14..724d1b6 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato@4x.png
new file mode 100644
index 0000000..351a0b9
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/legato@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main.png
index 7892a8a..a33d4c0 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main@4x.png
new file mode 100644
index 0000000..a5bfd6c
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/main@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu@4x.png
new file mode 100644
index 0000000..b7cfc60
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/menu@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices.png
index 3af3788..60b372c 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices@4x.png
new file mode 100644
index 0000000..00245a8
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Blue/voices@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button.png
old mode 100755
new mode 100644
index 4a1e19f..81d862d
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button@4x.png
new file mode 100644
index 0000000..f75d4a1
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/button@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/coords.xml b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/coords.xml
index 12edfb7..b007c76 100755
--- a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/coords.xml
+++ b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/coords.xml
@@ -5,15 +5,15 @@
-
-
-
+
+
+
-
+
@@ -33,30 +33,30 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
@@ -65,21 +65,21 @@
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
@@ -101,17 +101,17 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob.png
old mode 100755
new mode 100644
index 2525342..ad97bcc
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob@2x.png
old mode 100755
new mode 100644
index 8f0d205..6b6d0ac
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob@2x.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob@4x.png
new file mode 100644
index 0000000..51aed75
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/knob@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato.png
old mode 100755
new mode 100644
index 34e9a9c..2f4e6fb
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato@4x.png
new file mode 100644
index 0000000..f6da12d
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/legato@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main.png
old mode 100755
new mode 100644
index 4081feb..9c24572
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main@2x.png
old mode 100755
new mode 100644
index def7436..39b555d
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main@2x.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main@4x.png
new file mode 100644
index 0000000..2bfedc9
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/main@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu.png
old mode 100755
new mode 100644
index b7cfc60..dacd4ac
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu@4x.png
new file mode 100644
index 0000000..b7cfc60
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/menu@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices.png
old mode 100755
new mode 100644
index 21e9b4d..ca9ef6d
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices@4x.png
new file mode 100644
index 0000000..07513f7
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Classic/voices@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button.png
index fa95a0a..dd8a52f 100644
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button@2x.png
old mode 100755
new mode 100644
index 5082889..4aebd95
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button@2x.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button@4x.png
new file mode 100644
index 0000000..b345dac
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/button@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/coords.xml b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/coords.xml
index 94e3016..7d79607 100755
--- a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/coords.xml
+++ b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/coords.xml
@@ -5,32 +5,32 @@
-
+
-
-
+
+
-
+
-
+
-
-
-
+
+
+
@@ -45,9 +45,9 @@
-
-
-
+
+
+
@@ -58,22 +58,22 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
@@ -83,34 +83,34 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob.png
old mode 100755
new mode 100644
index 9d3b6b7..e455848
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob@2x.png
old mode 100755
new mode 100644
index 2aaf8e8..3f922fe
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob@2x.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob@4x.png
new file mode 100644
index 0000000..4b7e209
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/knob@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato.png
old mode 100755
new mode 100644
index 9eb3b07..f3f175f
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato@4x.png
new file mode 100644
index 0000000..351a0b9
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/legato@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main.png
old mode 100755
new mode 100644
index 4598deb..66ef332
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main@4x.png
new file mode 100644
index 0000000..8524d5b
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/main@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu.png
old mode 100755
new mode 100644
index 2b5e0b6..1ac639a
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu@2x.png
old mode 100755
new mode 100644
index 2dc9647..1ac639a
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu@2x.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu@2x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu@4x.png
new file mode 100644
index 0000000..1ac639a
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/menu@4x.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices.png
old mode 100755
new mode 100644
index f8126f1..f0c3d02
Binary files a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices.png and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices.png differ
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices@2x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices@2x.png
old mode 100755
new mode 100644
diff --git a/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices@4x.png b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices@4x.png
new file mode 100644
index 0000000..00245a8
Binary files /dev/null and b/Documents/discoDSP/OB-Xd/Themes/discoDSP Grey/voices@4x.png differ
diff --git a/OB-Xd.jucer b/OB-Xd.jucer
index d71f44f..9c82b7a 100644
--- a/OB-Xd.jucer
+++ b/OB-Xd.jucer
@@ -1,6 +1,6 @@
-
+
+
+
+
+
+
+
@@ -69,6 +78,8 @@
+
+
@@ -80,7 +91,7 @@
stripLocalSymbols="0" linkTimeOptimisation="0"/>
+ enablePluginBinaryCopyStep="1" macOSDeploymentTarget="10.9"/>
@@ -149,20 +160,20 @@
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 1ccb855..7751f60 100644
--- a/README.md
+++ b/README.md
@@ -15,4 +15,4 @@ Latest binaries can be downloaded at https://www.discodsp.com/obxd/
# Building
-Source code can be compiled with [JUCE 5.4.7](https://github.com/juce-framework/JUCE/archive/5.4.7.zip) and VST3 SDK.
+Source code can be compiled with [JUCE 6.0.5](https://github.com/juce-framework/JUCE/releases/tag/6.0.5) and VST3 SDK.
diff --git a/Source/Components/PresetBar.cpp b/Source/Components/PresetBar.cpp
index 354cb26..8864f04 100644
--- a/Source/Components/PresetBar.cpp
+++ b/Source/Components/PresetBar.cpp
@@ -34,10 +34,22 @@ PresetBar::PresetBar (ObxdAudioProcessorEditor &gui)
//[Constructor_pre] You can add your own custom stuff here..
//[/Constructor_pre]
- presetNameLb.reset (new juce::Label ("new label",
+ presetNameLb.reset (new CustomLabel ("new label",
TRANS("---\n")));
addAndMakeVisible (presetNameLb.get());
- presetNameLb->setFont (juce::Font (15.00f, juce::Font::plain).withTypefaceStyle ("Regular"));
+
+#ifdef JUCE_MAC
+ presetNameLb->setFont (juce::Font ("Helvetica Neue", 16.00f, juce::Font::plain).withTypefaceStyle ("Bold"));
+#endif
+
+#ifdef JUCE_WINDOWS
+ presetNameLb->setFont (juce::Font ("Arial", 16.00f, juce::Font::plain).withTypefaceStyle ("Bold"));
+#endif
+
+#ifdef JUCE_LINUX
+ presetNameLb->setFont (juce::Font ("DejaVu Sans", 16.00f, juce::Font::plain).withTypefaceStyle ("Bold"));
+#endif
+
presetNameLb->setJustificationType (juce::Justification::centred);
presetNameLb->setEditable (false, false, false);
presetNameLb->setColour (juce::TextEditor::textColourId, juce::Colours::black);
@@ -70,13 +82,16 @@ PresetBar::PresetBar (ObxdAudioProcessorEditor &gui)
drawable1 = juce::Drawable::createFromImageData (presetnavigation_svg, presetnavigation_svgSize);
//[UserPreSize]
+ presetNameLb->leftClicked = [this](juce::Point pos){
+ this->leftClicked(pos);
+ };
//[/UserPreSize]
setSize (471, 40);
//[Constructor] You can add your own custom stuff here..
- startTimer(500);
+ startTimer(50);
//[/Constructor]
}
@@ -136,12 +151,14 @@ void PresetBar::buttonClicked (juce::Button* buttonThatWasClicked)
{
//[UserButtonCode_previousBtn] -- add your button handler code here..
editor.prevProgram();
+ //update();
//[/UserButtonCode_previousBtn]
}
else if (buttonThatWasClicked == nextBtn.get())
{
//[UserButtonCode_nextBtn] -- add your button handler code here..
editor.nextProgram();
+ //update();
//[/UserButtonCode_nextBtn]
}
diff --git a/Source/Components/PresetBar.h b/Source/Components/PresetBar.h
index dd05f21..f09a9dc 100644
--- a/Source/Components/PresetBar.h
+++ b/Source/Components/PresetBar.h
@@ -22,6 +22,19 @@
//[Headers] -- You can add your own extra header files here --
#include
class ObxdAudioProcessorEditor;
+class CustomLabel: public juce::Label {
+public:
+ CustomLabel (const String& componentName = String(),
+ const String& labelText = String()): juce::Label(componentName, labelText) {
+
+ }
+ std::function pos)> leftClicked;
+ void mouseDown (const juce::MouseEvent& event) override {
+ if (this->getBounds().contains(event.getMouseDownPosition()) && event.mods.isLeftButtonDown()){
+ leftClicked(event.getScreenPosition());
+ }
+ };
+};
//[/Headers]
@@ -47,6 +60,9 @@ public:
//[UserMethods] -- You can add your own custom methods in this section.
void timerCallback() override;
void update();
+
+
+ std::function &pos)> leftClicked;
//[/UserMethods]
void paint (juce::Graphics& g) override;
@@ -64,7 +80,7 @@ private:
//[/UserVariables]
//==============================================================================
- std::unique_ptr presetNameLb;
+ std::unique_ptr presetNameLb;
std::unique_ptr previousBtn;
std::unique_ptr nextBtn;
std::unique_ptr drawable1;
diff --git a/Source/Components/ScaleComponent.cpp b/Source/Components/ScaleComponent.cpp
new file mode 100644
index 0000000..e7560ad
--- /dev/null
+++ b/Source/Components/ScaleComponent.cpp
@@ -0,0 +1,138 @@
+/*
+ ==============================================================================
+
+ ScaleComponent.cpp
+ Created: 27 Aug 2021 1:26:08pm
+ Author: discoDSP
+
+ ==============================================================================
+*/
+#include "../PluginProcessor.h"
+#include "ScaleComponent.h"
+
+
+
+//==============================================================================
+ScalableComponent::ScalableComponent(ObxdAudioProcessor* owner_)
+ : scaleFactor(0.0f),
+ isHighResolutionDisplay(false),
+ processor(owner_)
+{
+ setScaleFactor(1.0f, false);
+}
+
+ScalableComponent::~ScalableComponent()
+{
+}
+
+void ScalableComponent::setScaleFactor(float newScaleFactor, bool newIsHighResolutionDisplay)
+{
+ // until we get a freely scalable editor !!!
+ jassert(newScaleFactor == 1.0f || newScaleFactor == 1.5f || newScaleFactor == 2.0f);
+
+ if (scaleFactor != newScaleFactor || isHighResolutionDisplay != newIsHighResolutionDisplay)
+ {
+ scaleFactor = newScaleFactor;
+ isHighResolutionDisplay = newIsHighResolutionDisplay;
+
+ scaleFactorChanged();
+ }
+}
+
+float ScalableComponent::getScaleImage(){
+ float scale = 1.0;
+ if (!isHighResolutionDisplay)
+ {
+ if (getScaleFactor() == 1.5f)
+ {
+ scale= 0.75f;
+ }
+ else if (getScaleFactor() == 2.0f)
+ {
+ scale= 0.5f;
+ }
+ } else {
+ if (getScaleFactor() == 1.0f) //2x image
+ {
+ scale= 0.5f;
+ }
+ else if (getScaleFactor() == 1.5f) //4x images =>150%
+ {
+ scale= (0.25f + 0.125f);
+ }
+ else if (getScaleFactor() == 2.0f) //4x images =>200x
+ {
+ scale= 0.5f;
+ }
+ }
+ return scale;
+};
+
+float ScalableComponent::getScaleFactor() const
+{
+ return scaleFactor;
+}
+
+bool ScalableComponent::getIsHighResolutionDisplay() const
+{
+ return isHighResolutionDisplay;
+}
+
+int ScalableComponent::getScaleInt(){
+ int scaleFactorInt = 1;
+ if (scaleFactor == 1.5f)
+ scaleFactorInt = 2;
+ if (scaleFactor == 2.0f)
+ scaleFactorInt = 4;
+
+ if (isHighResolutionDisplay){
+ scaleFactorInt *= 2;
+ }
+ if (scaleFactorInt> 4){
+ scaleFactorInt=4;
+ }
+ return scaleFactorInt;
+}
+
+Image ScalableComponent::getScaledImageFromCache(const String& imageName,
+ float scaleFactor,
+ bool isHighResolutionDisplay)
+{
+ jassert(scaleFactor == 1.0f || scaleFactor == 1.5f || scaleFactor == 2.0f);
+ this->isHighResolutionDisplay = isHighResolutionDisplay;
+ int scaleFactorInt = getScaleInt();
+ String resourceName = imageName + "_png";
+ if (scaleFactorInt != 1){
+ resourceName = imageName + String::formatted("%dx_png", scaleFactorInt);
+ }
+
+
+ int size = 0;
+ File skin;
+ if (processor){
+ File f(processor->getCurrentSkinFolder());
+ if (f.isDirectory()){
+ skin=f;
+ }
+ }
+
+ const char* data = nullptr;
+ String image_file = imageName;
+ if (scaleFactorInt ==1)
+ image_file += ".png";
+ else
+ image_file += String::formatted("@%dx.png", scaleFactorInt);
+ DBG(" Loaf image: " << image_file);
+ File file = skin.getChildFile(image_file);
+ if (file.exists()){
+ return ImageCache::getFromFile(file);
+ } else {
+ data = BinaryData::getNamedResource((const char*)resourceName.toUTF8(), size);
+ DBG(" Image: " << resourceName);
+ return ImageCache::getFromMemory(data, size);
+ }
+}
+
+void ScalableComponent::scaleFactorChanged()
+{
+}
diff --git a/Source/Components/ScaleComponent.h b/Source/Components/ScaleComponent.h
new file mode 100644
index 0000000..6c37be1
--- /dev/null
+++ b/Source/Components/ScaleComponent.h
@@ -0,0 +1,213 @@
+/*
+ ==============================================================================
+
+ ScaleComponent.h
+ Created: 27 Aug 2021 1:26:08pm
+ Author: discoDSP
+
+ ==============================================================================
+*/
+
+#pragma once
+
+//==============================================================================
+#include
+class ObxdAudioProcessor;
+
+
+
+
+//==============================================================================
+class ScalableComponent
+{
+public:
+ ~ScalableComponent();
+ int getScaleInt();
+ void setScaleFactor(float newScaleFactor, bool newIsHighResolutionDisplay);
+ float getScaleImage();
+ float getScaleFactor() const;
+ bool getIsHighResolutionDisplay() const;
+
+ virtual void scaleFactorChanged();
+
+protected:
+ ScalableComponent(ObxdAudioProcessor* owner_);
+
+ Image getScaledImageFromCache(const String& imageName, float scaleFactor, bool isHighResolutionDisplay);
+
+private:
+ ObxdAudioProcessor* processor;
+ float scaleFactor;
+ bool isHighResolutionDisplay;
+
+};
+
+
+//==============================================================================
+class CustomLookAndFeel : public LookAndFeel_V3,
+ public ScalableComponent
+{
+public:
+ CustomLookAndFeel(ObxdAudioProcessor* owner_):LookAndFeel_V3(), ScalableComponent(owner_) {
+ this->setColour(PopupMenu::backgroundColourId, Colour(20, 20, 20));
+ this->setColour(PopupMenu::textColourId, Colour(245, 245, 245));
+ this->setColour(PopupMenu::highlightedBackgroundColourId, Colour(60, 60, 60));
+ this->setColour(Label::textColourId, Colour(245, 245, 245));
+ };
+
+
+ PopupMenu::Options getOptionsForComboBoxPopupMenu (ComboBox& box, Label& label) override
+ {
+ PopupMenu::Options option = LookAndFeel_V3::getOptionsForComboBoxPopupMenu(box, label);
+ return option.withStandardItemHeight (label.getHeight()/ getScaleFactor());
+ };
+ Font getPopupMenuFont () override
+ {
+
+ float scaleFactor = getScaleFactor();
+ DBG("getPopupMenuFont::scaleFactor " << scaleFactor);
+ if (scaleFactor > 1.0) scaleFactor *= 0.75;
+
+
+ #ifdef JUCE_MAC
+ return Font("Helvetica Neue", 16.0 * scaleFactor, Font::plain);
+ #endif
+
+ #ifdef JUCE_WINDOWS
+ return Font("Arial", 16.0 * scaleFactor, Font::plain);
+ #endif
+
+ #ifdef JUCE_LINUX
+ return Font("DejaVu Sans", 16.0 * scaleFactor, Font::plain);
+ #endif
+ }
+ /*
+ void drawPopupMenuItem (Graphics& g, const Rectangle& area,
+ const bool isSeparator, const bool isActive,
+ const bool isHighlighted, const bool isTicked,
+ const bool hasSubMenu, const String& text,
+ const String& shortcutKeyText,
+ const Drawable* icon, const Colour* const textColourToUse)
+ {
+ if (isSeparator)
+ {
+ auto r = area.reduced (5, 0);
+ r.removeFromTop (r.getHeight() / 2 - 1);
+
+ g.setColour (Colour (0x33000000));
+ g.fillRect (r.removeFromTop (1));
+
+ g.setColour (Colour (0x66ffffff));
+ g.fillRect (r.removeFromTop (1));
+ }
+ else
+ {
+ auto textColour = findColour (PopupMenu::textColourId);
+
+ if (textColourToUse != nullptr)
+ textColour = *textColourToUse;
+
+ auto r = area.reduced (1);
+
+ if (isHighlighted)
+ {
+ g.setColour (findColour (PopupMenu::highlightedBackgroundColourId));
+ g.fillRect (r);
+
+ g.setColour (findColour (PopupMenu::highlightedTextColourId));
+ }
+ else
+ {
+ g.setColour (textColour);
+ }
+
+ if (! isActive)
+ g.setOpacity (0.3f);
+
+ Font font (getPopupMenuFont());
+
+ auto maxFontHeight = (float) area.getHeight() / 1.3f;
+
+ if (font.getHeight() > maxFontHeight)
+ font.setHeight (maxFontHeight);
+
+ g.setFont (font);
+
+ auto iconArea = r.removeFromLeft ((r.getHeight() * 5) / 4).reduced (3).toFloat();
+
+ if (icon != nullptr)
+ {
+ icon->drawWithin (g, iconArea, RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, 1.0f);
+ }
+ else if (isTicked)
+ {
+ auto tick = getTickShape (1.0f);
+ g.fillPath (tick, tick.getTransformToScaleToFit (iconArea, true));
+ }
+
+ if (hasSubMenu)
+ {
+ auto arrowH = 0.6f * getPopupMenuFont().getAscent();
+
+ auto x = (float) r.removeFromRight ((int) arrowH).getX();
+ auto halfH = (float) r.getCentreY();
+
+ Path p;
+ p.addTriangle (x, halfH - arrowH * 0.5f,
+ x, halfH + arrowH * 0.5f,
+ x + arrowH * 0.6f, halfH);
+
+ g.fillPath (p);
+ }
+
+ r.removeFromRight (3);
+ g.drawFittedText (text, r, Justification::centredLeft, 1);
+
+ if (shortcutKeyText.isNotEmpty())
+ {
+ Font f2 (font);
+ f2.setHeight (f2.getHeight() * 0.75f);
+ f2.setHorizontalScale (0.95f);
+ g.setFont (f2);
+
+ g.drawText (shortcutKeyText, r, Justification::centredRight, true);
+ }
+ }
+ }
+ void drawLabel (Graphics& g, Label& label) override
+ {
+ g.fillAll (label.findColour (Label::backgroundColourId));
+
+ if (! label.isBeingEdited())
+ {
+ auto alpha = label.isEnabled() ? 1.0f : 0.5f;
+ const Font font (getLabelFont (label));
+
+ g.setColour (label.findColour (Label::textColourId).withMultipliedAlpha (alpha));
+ g.setFont (font);
+
+ auto textArea = getLabelBorderSize (label).subtractedFrom (label.getLocalBounds());
+ textArea = textArea.toFloat().transformedBy(AffineTransform::scale(getScaleFactor())).toNearestInt();
+ g.drawFittedText (label.getText(), textArea, label.getJustificationType(),
+ jmax (1, (int) ((float) textArea.getHeight() / font.getHeight())),
+ label.getMinimumHorizontalScale());
+
+ g.setColour (label.findColour (Label::outlineColourId).withMultipliedAlpha (alpha));
+ }
+ else if (label.isEnabled())
+ {
+ g.setColour (label.findColour (Label::outlineColourId));
+ }
+
+ g.drawRect (label.getLocalBounds());
+ }
+ BorderSize getLabelBorderSize (Label& label)
+ {
+ BorderSize boder = label.getBorderSize();
+ Rectangle rec = Rectangle::leftTopRightBottom(boder.getLeft(), boder.getTop(), boder.getRight(), boder.getBottom());
+ Rectangle rec2 = rec.toFloat().transformedBy(AffineTransform::scale(getScaleFactor())).toNearestInt();
+
+ return BorderSize(rec2.getX(), rec2.getY(), rec2.getRight(), rec2.getBottom() );
+ }
+ */
+};
diff --git a/Source/Gui/ButtonList.h b/Source/Gui/ButtonList.h
index c65ec53..c1641ce 100755
--- a/Source/Gui/ButtonList.h
+++ b/Source/Gui/ButtonList.h
@@ -23,19 +23,32 @@
*/
#pragma once
#include "../Source/Engine/SynthEngine.h"
+class ObxdAudioProcessor;
-class ButtonList : public ComboBox
+class ButtonList : public ComboBox, public ScalableComponent
{
+ juce::String img_name;
public:
- ButtonList (Image k, int fh) : ComboBox("cb")
+ ButtonList (juce::String nameImg, int fh, ObxdAudioProcessor *owner) : ComboBox("cb"), ScalableComponent(owner), img_name(nameImg)
{
- kni = k;
+ scaleFactorChanged();
count = 0;
h2 = fh;
- w2 = k.getWidth();
+ w2 = kni.getWidth();
}
//int addItem
-
+ void scaleFactorChanged() override
+ {
+ kni = getScaledImageFromCache(img_name, getScaleFactor(), getIsHighResolutionDisplay());
+ /*
+ backgroundImage =
+ allImage.getClippedImage(Rectangle(0,
+ allImage.getHeight() / 2,
+ allImage.getWidth(),
+ allImage.getHeight() / 2));
+ */
+ repaint();
+ }
// Source: https://git.iem.at/audioplugins/IEMPluginSuite/-/blob/master/resources/customComponents/ReverseSlider.h
public:
class ButtonListAttachment : public juce::AudioProcessorValueTreeState::ComboBoxAttachment
@@ -94,7 +107,7 @@ public:
void paintOverChildren (Graphics& g) override
{
int ofs = getSelectedId() - 1;
- g.drawImage(kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs, w2, h2);
+ g.drawImage(kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs * getScaleInt(), w2 * getScaleInt() , h2* getScaleInt());
}
private:
diff --git a/Source/Gui/ImageButton.h b/Source/Gui/ImageButton.h
new file mode 100644
index 0000000..40dbe67
--- /dev/null
+++ b/Source/Gui/ImageButton.h
@@ -0,0 +1,87 @@
+/*
+ ==============================================================================
+ This file is part of Obxd synthesizer.
+
+ Copyright � 2013-2014 Filatov Vadim
+
+ Contact author via email :
+ justdat_@_e1.ru
+
+ This file may be licensed under the terms of of the
+ GNU General Public License Version 2 (the ``GPL'').
+
+ Software distributed under the License is distributed
+ on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ express or implied. See the GPL for the specific language
+ governing rights and limitations.
+
+ You should have received a copy of the GPL along with this
+ program. If not, go to http://www.gnu.org/licenses/gpl.html
+ or write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ==============================================================================
+ */
+#pragma once
+#include "../Source/Engine/SynthEngine.h"
+class ObxdAudioProcessor;
+
+
+class ImageMenu : public ImageButton,
+ public ScalableComponent
+{
+ juce::String img_name;
+public:
+ ImageMenu(juce::String nameImg, ObxdAudioProcessor* owner_)
+ : ScalableComponent(owner_), img_name(nameImg)
+ {
+ scaleFactorChanged();
+
+ setOpaque(false);
+ setVisible(true);
+ }
+
+
+ void scaleFactorChanged() override
+ {
+ const float scaleFactor = getScaleFactor();
+ const bool isHighResolutionDisplay = getIsHighResolutionDisplay();
+
+ Image normalImage = getScaledImageFromCache(img_name, scaleFactor, isHighResolutionDisplay);
+ Image downImage = getScaledImageFromCache(img_name, scaleFactor, isHighResolutionDisplay);
+
+ const bool resizeButtonNowToFitThisImage = false;
+ const bool rescaleImagesWhenButtonSizeChanges = true;
+ const bool preserveImageProportions = true;
+ /*
+ false,
+ true,
+ true,
+ image,
+ 1.0f, // menu transparency
+ Colour(),
+ image,
+ 1.0f, // menu hover transparency
+ Colour(),
+ image,
+ 0.3f, // menu click transparency
+ Colour());
+ */
+ setImages(resizeButtonNowToFitThisImage,
+ rescaleImagesWhenButtonSizeChanges,
+ preserveImageProportions,
+ normalImage,
+ 1.0f, // menu transparency
+ Colour(),
+ normalImage,
+ 1.0f, // menu hover transparency
+ Colour(),
+ downImage,
+ 0.3f, // menu click transparency
+ Colour());
+
+ repaint();
+ }
+
+
+protected:
+};
diff --git a/Source/Gui/Knob.h b/Source/Gui/Knob.h
old mode 100755
new mode 100644
index 4630b49..8d8b36b
--- a/Source/Gui/Knob.h
+++ b/Source/Gui/Knob.h
@@ -23,9 +23,11 @@
*/
#pragma once
#include "../Source/Engine/SynthEngine.h"
-
-class Knob : public Slider
+#include "../Components/ScaleComponent.h"
+class ObxdAudioProcessor;
+class Knob : public Slider, public ScalableComponent
{
+ juce::String img_name;
public:
//Knob(Image image, const int numFrames, const bool stripIsHorizontal) : Slider("Knob")
//{
@@ -34,14 +36,27 @@ public:
// setSliderStyle(RotaryVerticalDrag);
// setRange(0.0f, 1.0f, 0.001f);
//}
- Knob (Image k, int fh) : Slider("Knob")
+ Knob (juce::String name, int fh, ObxdAudioProcessor* owner_) : Slider("Knob"), ScalableComponent(owner_), img_name(name)
{
+ scaleFactorChanged();
+
h2 = fh;
- w2 = k.getWidth();
- numFr = k.getHeight() / h2;
- kni = k;
+ w2 = kni.getWidth();
+ numFr = kni.getHeight() / h2;
+
};
-
+ void scaleFactorChanged() override
+ {
+ kni = getScaledImageFromCache(img_name, getScaleFactor(), getIsHighResolutionDisplay());
+ /*
+ backgroundImage =
+ allImage.getClippedImage(Rectangle(0,
+ allImage.getHeight() / 2,
+ allImage.getWidth(),
+ allImage.getHeight() / 2));
+ */
+ repaint();
+ }
// Source: https://git.iem.at/audioplugins/IEMPluginSuite/-/blob/master/resources/customComponents/ReverseSlider.h
public:
class KnobAttachment : public juce::AudioProcessorValueTreeState::SliderAttachment
@@ -68,7 +83,7 @@ public:
float val = parameter->getValue();
//sliderToControl->setValue(parameter->convertFrom0to1(val0to1));
sliderToControl->setValue(val, NotificationType::dontSendNotification);
- DBG(" Slider: " << parameter->name << " " << sliderToControl->getValue() << " Parameter: "<< " " << parameter->getValue());
+ //DBG(" Slider: " << parameter->name << " " << sliderToControl->getValue() << " Parameter: "<< " " << parameter->getValue());
}
virtual ~KnobAttachment() = default;
@@ -87,7 +102,7 @@ public:
void paint (Graphics& g) override
{
int ofs = (int) ((getValue() - getMinimum()) / (getMaximum() - getMinimum()) * (numFr - 1));
- g.drawImage (kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs, w2, h2);
+ g.drawImage (kni, 0, 0, getWidth(), getHeight(), 0, h2 * ofs * getScaleInt(), w2 * getScaleInt(), h2 * getScaleInt());
}
~Knob() override {};
diff --git a/Source/Gui/TooglableButton.h b/Source/Gui/TooglableButton.h
old mode 100755
new mode 100644
index 1f80d96..7aee2f0
--- a/Source/Gui/TooglableButton.h
+++ b/Source/Gui/TooglableButton.h
@@ -23,14 +23,18 @@
*/
#pragma once
#include "../Source/Engine/SynthEngine.h"
+#include "../Components/ScaleComponent.h"
+class ObxdAudioProcessor;
-class TooglableButton : public ImageButton
+class TooglableButton : public ImageButton, public ScalableComponent
{
+ juce::String img_name;
public:
- TooglableButton (Image k) : ImageButton()
+ TooglableButton (juce::String name, ObxdAudioProcessor *owner) : ImageButton(),ScalableComponent(owner), img_name(name)
{
//this->setImages
- kni = k;
+ //kni = k;
+ scaleFactorChanged();
//toogled = false;
width = kni.getWidth();
height = kni.getHeight();
@@ -38,6 +42,18 @@ public:
h2 = height / 2;
this->setClickingTogglesState (true);
}
+ void scaleFactorChanged() override
+ {
+ kni = getScaledImageFromCache(img_name, getScaleFactor(), getIsHighResolutionDisplay());
+ /*
+ backgroundImage =
+ allImage.getClippedImage(Rectangle(0,
+ allImage.getHeight() / 2,
+ allImage.getWidth(),
+ allImage.getHeight() / 2));
+ */
+ repaint();
+ }
~TooglableButton() override{
};
@@ -102,7 +118,7 @@ public:
offset = 1;
}
- g.drawImage(kni, 0, 0, getWidth(), getHeight(), 0, offset * h2, w2, h2);
+ g.drawImage(kni, 0, 0, getWidth(), getHeight(), 0, offset * h2 * getScaleInt() , w2 * getScaleInt(), h2 * getScaleInt());
}
/*
void setValue (float state, int notify)
diff --git a/Source/Images/main.png b/Source/Images/main.png
index d931cff..9ed3ea2 100644
Binary files a/Source/Images/main.png and b/Source/Images/main.png differ
diff --git a/Source/Images/main.psd b/Source/Images/main.psd
index c7b831e..4eb01c9 100644
Binary files a/Source/Images/main.psd and b/Source/Images/main.psd differ
diff --git a/Source/Images/main@2x.png b/Source/Images/main@2x.png
new file mode 100644
index 0000000..50fd206
Binary files /dev/null and b/Source/Images/main@2x.png differ
diff --git a/Source/Images/main@4x.png b/Source/Images/main@4x.png
new file mode 100644
index 0000000..8f091ec
Binary files /dev/null and b/Source/Images/main@4x.png differ
diff --git a/Source/Images/menu@2x.png b/Source/Images/menu@2x.png
new file mode 100755
index 0000000..d1fcc71
Binary files /dev/null and b/Source/Images/menu@2x.png differ
diff --git a/Source/Images/menu@4x.png b/Source/Images/menu@4x.png
new file mode 100755
index 0000000..d1fcc71
Binary files /dev/null and b/Source/Images/menu@4x.png differ
diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp
index 3c4f454..3167403 100755
--- a/Source/PluginEditor.cpp
+++ b/Source/PluginEditor.cpp
@@ -10,11 +10,14 @@ It contains the basic startup code for a Juce application.
#include "PluginProcessor.h"
#include "PluginEditor.h"
#include
+#include "Gui/ImageButton.h"
// #include "GUI/BinaryData.h"
+#include "Utils.h"
+
//==============================================================================
ObxdAudioProcessorEditor::ObxdAudioProcessorEditor (ObxdAudioProcessor& ownerFilter)
- : AudioProcessorEditor (&ownerFilter), processor (ownerFilter),
+ : AudioProcessorEditor (&ownerFilter), ScalableComponent(&ownerFilter), processor (ownerFilter),
skinFolder (processor.getSkinFolder()),
progStart (3000),
bankStart (2000),
@@ -22,11 +25,13 @@ ObxdAudioProcessorEditor::ObxdAudioProcessorEditor (ObxdAudioProcessor& ownerFil
skins (processor.getSkinFiles()),
banks (processor.getBankFiles())
{
- LookAndFeel& lf = getLookAndFeel();
+ setLookAndFeel(new CustomLookAndFeel(&this->processor));
+
+ //LookAndFeel& lf = getLookAndFeel();
// Popup Menu Look and Feel
- lf.setColour(PopupMenu::backgroundColourId, Colour(20, 20, 20));
- lf.setColour(PopupMenu::textColourId, Colour(245, 245, 245));
- lf.setColour(PopupMenu::highlightedBackgroundColourId, Colour(60, 60, 60));
+ //lf.setColour(PopupMenu::backgroundColourId, Colour(20, 20, 20));
+ //lf.setColour(PopupMenu::textColourId, Colour(245, 245, 245));
+ //lf.setColour(PopupMenu::highlightedBackgroundColourId, Colour(60, 60, 60));
//skinFolder = ownerFilter.getCurrentSkinFolder(); // initialized above
commandManager.registerAllCommandsForTarget(this);
@@ -52,10 +57,25 @@ ObxdAudioProcessorEditor::ObxdAudioProcessorEditor (ObxdAudioProcessor& ownerFil
DBG("W: " <getTagName() == "PROPERTIES"){
+ forEachXmlChildElementWithTagName(*doc, child, "VALUE"){
+ if (child->hasAttribute("NAME") && child->hasAttribute("x") && child->hasAttribute("y")) {
+ String name = child->getStringAttribute("NAME");
+ int x = child->getIntAttribute("x");
+ int y = child->getIntAttribute("y");
+ int d = child->getIntAttribute("d");
+ int w = child->getIntAttribute("w");
+ int h = child->getIntAttribute("h");
+ DBG(" COmponent : " << name);
+ if (mappingComps[name] != nullptr){
+ if (dynamic_cast(mappingComps[name])){
+ mappingComps[name]->setBounds(transformBounds(x, y, d,d));
+ }
+ else if (dynamic_cast(mappingComps[name])){
+ mappingComps[name]->setBounds(transformBounds(x, y, w, h));
+ //((ButtonList *)mappingComps[name])->getRootMenu()->setLookAndFeel(& getLookAndFeel());
+ }
+
+ else if (dynamic_cast(mappingComps[name])){
+ mappingComps[name]->setBounds(transformBounds(x, y, w, h));
+ }
+ else if (dynamic_cast(mappingComps[name])){
+ mappingComps[name]->setBounds(transformBounds(x, y, d, d));
+ }
+ else if (dynamic_cast(mappingComps[name])){
+ mappingComps[name]->setBounds(transformBounds(x, y, w, h));
+ }
+ }
+ }
+ }
+ }
+ }
}
void ObxdAudioProcessorEditor::loadSkin (ObxdAudioProcessor& ownerFilter)
{
@@ -85,13 +149,14 @@ void ObxdAudioProcessorEditor::loadSkin (ObxdAudioProcessor& ownerFilter)
toggleAttachments.clear();
imageButtons.clear();
popupMenus.clear();
+ mappingComps.clear();
ownerFilter.removeChangeListener (this);
- //File coords("/Users/jimmy/Downloads/coords.xml");
+
skinFolder = ownerFilter.getCurrentSkinFolder();
File coords = skinFolder.getChildFile ("coords.xml");
bool useClassicSkin = coords.existsAsFile();
if (!useClassicSkin) {
- addMenuButton (14, 25, 20, ImageCache::getFromMemory(BinaryData::menu_png, BinaryData::menu_pngSize));
+ addMenuButton (14, 25, 20, "menu");
rebuildComponents (processor);
return;
}
@@ -117,135 +182,336 @@ void ObxdAudioProcessorEditor::loadSkin (ObxdAudioProcessor& ownerFilter)
int w = child->getIntAttribute("w");
int h = child->getIntAttribute("h");
- if (name == "guisize"){
- xScreen = x;
- yScreen = y;
- if (processor.getShowPresetBar()) {
- setSize(xScreen, yScreen +40);
- }
- else {
- setSize(xScreen, yScreen);
- }
-
+
+ if (name == "resonanceKnob"){
+ resonanceKnob = addKnob (x, y, d, ownerFilter, RESONANCE, "Resonance", 0);
+ mappingComps["resonanceKnob"] = resonanceKnob;
}
+ if (name == "cutoffKnob"){
+ cutoffKnob = addKnob (x, y, d, ownerFilter, CUTOFF, "Cutoff", 0.4);
+ mappingComps["cutoffKnob"] = cutoffKnob;
+ }
+ if (name == "filterEnvelopeAmtKnob"){
+ filterEnvelopeAmtKnob = addKnob (x, y, d, ownerFilter, ENVELOPE_AMT, "Envelope", 0);
+ mappingComps["filterEnvelopeAmtKnob"] = filterEnvelopeAmtKnob;
+ }
+ if (name == "multimodeKnob"){
+ multimodeKnob = addKnob (x, y, d, ownerFilter, MULTIMODE, "Multimode", 0.5);
+ mappingComps["multimodeKnob"] = multimodeKnob;
+ }
+
+ if (name == "volumeKnob"){
+ volumeKnob = addKnob (x, y, d, ownerFilter, VOLUME, "Volume", 0.4);
+ mappingComps["volumeKnob"] = volumeKnob;
+ }
+ if (name == "portamentoKnob"){
+ portamentoKnob = addKnob (x, y, d, ownerFilter, PORTAMENTO, "Portamento", 0);
+ mappingComps["portamentoKnob"] = portamentoKnob;
+ }
+ if (name == "osc1PitchKnob"){
+ osc1PitchKnob = addKnob (x, y, d, ownerFilter, OSC1P, "Osc1Pitch", 0);
+ mappingComps["osc1PitchKnob"] = osc1PitchKnob;
+ }
+ if (name == "pulseWidthKnob"){
+ pulseWidthKnob = addKnob (x, y, d, ownerFilter, PW, "PW", 0);
+ mappingComps["pulseWidthKnob"] = pulseWidthKnob;
+ }
+ if (name == "osc2PitchKnob"){
+ osc2PitchKnob = addKnob (x, y, d, ownerFilter, OSC2P, "Osc2Pitch", 0);
+ mappingComps["osc2PitchKnob"] = osc2PitchKnob;
+ }
+
+ if (name == "osc1MixKnob"){
+ osc1MixKnob = addKnob (x, y, d, ownerFilter, OSC1MIX, "Osc1", 1);
+ mappingComps["osc1MixKnob"] = osc1MixKnob;
+ }
+ if (name == "osc2MixKnob"){
+ osc2MixKnob = addKnob (x, y, d, ownerFilter, OSC2MIX, "Osc2", 1);
+ mappingComps["osc2MixKnob"] = osc2MixKnob;
+ }
+ if (name == "noiseMixKnob"){
+ noiseMixKnob = addKnob (x, y, d, ownerFilter, NOISEMIX, "Noise", 0);
+ mappingComps["noiseMixKnob"] = noiseMixKnob;
+ }
+
+ if (name == "xmodKnob"){
+ xmodKnob = addKnob (x, y, d, ownerFilter, XMOD, "Xmod", 0);
+ mappingComps["xmodKnob"] = xmodKnob;
+ }
+ if (name == "osc2DetuneKnob"){
+ osc2DetuneKnob = addKnob (x, y, d, ownerFilter, OSC2_DET, "Detune", 0);
+ mappingComps["osc2DetuneKnob"] = osc2DetuneKnob;
+ }
+
+ if (name == "envPitchModKnob"){
+ envPitchModKnob = addKnob (x, y, d, ownerFilter, ENVPITCH, "PEnv", 0);
+ mappingComps["envPitchModKnob"] = envPitchModKnob;
+ }
+ if (name == "brightnessKnob"){
+ brightnessKnob = addKnob (x, y, d, ownerFilter, BRIGHTNESS, "Bri", 1);
+ mappingComps["brightnessKnob"] = brightnessKnob;
+ }
+
+ if (name == "attackKnob"){
+ attackKnob = addKnob (x, y, d, ownerFilter, LATK, "Atk", 0);
+ mappingComps["attackKnob"] = attackKnob;
+ }
+ if (name == "decayKnob"){ decayKnob = addKnob (x, y, d, ownerFilter, LDEC, "Dec", 0);
+ mappingComps["decayKnob"] = decayKnob;
+ }
+ if (name == "sustainKnob"){
+ sustainKnob = addKnob (x, y, d, ownerFilter, LSUS, "Sus", 1);
+ mappingComps["sustainKnob"] = sustainKnob;
+ }
+ if (name == "releaseKnob"){
+ releaseKnob = addKnob (x, y, d, ownerFilter, LREL, "Rel", 0);
+ mappingComps["releaseKnob"] = releaseKnob;
+ }
+
+ if (name == "fattackKnob"){
+ fattackKnob = addKnob (x, y, d, ownerFilter, FATK, "Atk", 0);
+ mappingComps["fattackKnob"] = fattackKnob;
+ }
+ if (name == "fdecayKnob"){
+ fdecayKnob = addKnob (x, y, d, ownerFilter, FDEC, "Dec", 0);
+ mappingComps["fdecayKnob"] = fdecayKnob;
+ }
+ if (name == "fsustainKnob"){
+ fsustainKnob = addKnob (x, y, d, ownerFilter, FSUS, "Sus", 1);
+ mappingComps["fsustainKnob"] = fsustainKnob;
+ }
+ if (name == "freleaseKnob"){
+ freleaseKnob = addKnob (x, y, d, ownerFilter, FREL, "Rel", 0);
+ mappingComps["freleaseKnob"] = freleaseKnob;
+ }
+
+ if (name == "lfoFrequencyKnob"){
+ lfoFrequencyKnob = addKnob (x, y, d, ownerFilter, LFOFREQ, "Freq", 0);
+ mappingComps["lfoFrequencyKnob"] = lfoFrequencyKnob;
+ }
+ if (name == "lfoAmt1Knob"){
+ lfoAmt1Knob = addKnob (x, y, d, ownerFilter, LFO1AMT, "Pitch", 0);
+ mappingComps["lfoAmt1Knob"] = lfoAmt1Knob;
+ }
+ if (name == "lfoAmt2Knob"){
+ lfoAmt2Knob = addKnob (x, y, d, ownerFilter, LFO2AMT, "PWM", 0);
+ mappingComps["lfoAmt2Knob"] = lfoAmt2Knob;
+ }
+
+ if (name == "lfoSinButton"){
+ lfoSinButton = addButton (x, y, w, h, ownerFilter, LFOSINWAVE, "Sin");
+ mappingComps["lfoSinButton"] = lfoSinButton;
+ }
+ if (name == "lfoSquareButton"){
+ lfoSquareButton = addButton (x, y, w, h, ownerFilter, LFOSQUAREWAVE, "SQ");
+ mappingComps["lfoSquareButton"] = lfoSquareButton;
+ }
+ if (name == "lfoSHButton"){
+ lfoSHButton = addButton (x, y, w, h, ownerFilter, LFOSHWAVE, "S&H");
+ mappingComps["lfoSHButton"] = lfoSHButton;
+ }
+
+ if (name == "lfoOsc1Button"){
+ lfoOsc1Button = addButton (x, y, w, h, ownerFilter, LFOOSC1, "Osc1");
+ mappingComps["lfoOsc1Button"] = lfoOsc1Button;
+ }
+ if (name == "lfoOsc2Button"){
+ lfoOsc2Button = addButton (x, y, w, h, ownerFilter, LFOOSC2, "Osc2");
+ mappingComps["lfoOsc2Button"] = lfoOsc2Button;
+ }
+ if (name == "lfoFilterButton"){
+ lfoFilterButton = addButton (x, y, w, h, ownerFilter, LFOFILTER, "Filt");
+ mappingComps["lfoFilterButton"] = lfoFilterButton;
+ }
+
+ if (name == "lfoPwm1Button"){
+ lfoPwm1Button = addButton (x, y, w, h, ownerFilter, LFOPW1, "Osc1");
+ mappingComps["lfoPwm1Button"] = lfoPwm1Button;
- if (name == "resonanceKnob"){ resonanceKnob = addKnob (x, y, d, ownerFilter, RESONANCE, "Resonance", 0); }
- if (name == "cutoffKnob"){ cutoffKnob = addKnob (x, y, d, ownerFilter, CUTOFF, "Cutoff", 0.4); }
- if (name == "filterEnvelopeAmtKnob"){ filterEnvelopeAmtKnob = addKnob (x, y, d, ownerFilter, ENVELOPE_AMT, "Envelope", 0); }
- if (name == "multimodeKnob"){ multimodeKnob = addKnob (x, y, d, ownerFilter, MULTIMODE, "Multimode", 0.5); }
+ }
+ if (name == "lfoPwm2Button"){
+ lfoPwm2Button = addButton (x, y, w, h, ownerFilter, LFOPW2, "Osc2");
+ mappingComps["lfoPwm2Button"] = lfoPwm2Button;
+ }
- if (name == "volumeKnob"){ volumeKnob = addKnob (x, y, d, ownerFilter, VOLUME, "Volume", 0.4); }
- if (name == "portamentoKnob"){ portamentoKnob = addKnob (x, y, d, ownerFilter, PORTAMENTO, "Portamento", 0); }
- if (name == "osc1PitchKnob"){ osc1PitchKnob = addKnob (x, y, d, ownerFilter, OSC1P, "Osc1Pitch", 0); }
- if (name == "pulseWidthKnob"){ pulseWidthKnob = addKnob (x, y, d, ownerFilter, PW, "PW", 0); }
- if (name == "osc2PitchKnob"){ osc2PitchKnob = addKnob (x, y, d, ownerFilter, OSC2P, "Osc2Pitch", 0); }
+ if (name == "hardSyncButton"){
+ hardSyncButton = addButton (x, y, w, h, ownerFilter, OSC2HS, "Sync");
+ mappingComps["hardSyncButton"] = hardSyncButton;
+ }
+ if (name == "osc1SawButton"){
+ osc1SawButton = addButton (x, y, w, h, ownerFilter, OSC1Saw, "S");
+ mappingComps["osc1SawButton"] = osc1SawButton;
+ }
+ if (name == "osc2SawButton"){
+ osc2SawButton = addButton (x, y, w, h, ownerFilter, OSC2Saw, "S");
+ mappingComps["osc2SawButton"] = osc2SawButton;
+ }
- if (name == "osc1MixKnob"){ osc1MixKnob = addKnob (x, y, d, ownerFilter, OSC1MIX, "Osc1", 1); }
- if (name == "osc2MixKnob"){ osc2MixKnob = addKnob (x, y, d, ownerFilter, OSC2MIX, "Osc2", 1); }
- if (name == "noiseMixKnob"){ noiseMixKnob = addKnob (x, y, d, ownerFilter, NOISEMIX, "Noise", 0); }
+ if (name == "osc1PulButton"){
+ osc1PulButton = addButton (x, y, w, h, ownerFilter, OSC1Pul, "P");
+ mappingComps["osc1PulButton"] = osc1PulButton;
+ }
+ if (name == "osc2PulButton"){
+ osc2PulButton = addButton (x, y, w, h, ownerFilter, OSC2Pul, "P");
+ mappingComps["osc2PulButton"] = osc2PulButton;
+ }
- if (name == "xmodKnob"){ xmodKnob = addKnob (x, y, d, ownerFilter, XMOD, "Xmod", 0); }
- if (name == "osc2DetuneKnob"){ osc2DetuneKnob = addKnob (x, y, d, ownerFilter, OSC2_DET, "Detune", 0); }
+ if (name == "pitchQuantButton"){
+ pitchQuantButton = addButton (x, y, w, h, ownerFilter, OSCQuantize, "Step");
+ mappingComps["pitchQuantButton"] = pitchQuantButton;
+ }
- if (name == "envPitchModKnob"){ envPitchModKnob = addKnob (x, y, d, ownerFilter, ENVPITCH, "PEnv", 0); }
- if (name == "brightnessKnob"){ brightnessKnob = addKnob (x, y, d, ownerFilter, BRIGHTNESS, "Bri", 1); }
+ if (name == "filterBPBlendButton"){
+ filterBPBlendButton = addButton (x, y, w, h, ownerFilter, BANDPASS, "Bp");
+ mappingComps["filterBPBlendButton"] = filterBPBlendButton;
+ }
+ if (name == "fourPoleButton"){
+ fourPoleButton = addButton (x, y, w, h, ownerFilter, FOURPOLE, "24");
+ mappingComps["fourPoleButton"] = fourPoleButton;
+ }
+ if (name == "filterHQButton"){
+ filterHQButton = addButton (x, y, w, h, ownerFilter, FILTER_WARM, "HQ");
+ mappingComps["filterHQButton"] = filterHQButton;
+ }
- if (name == "attackKnob"){ attackKnob = addKnob (x, y, d, ownerFilter, LATK, "Atk", 0); }
- if (name == "decayKnob"){ decayKnob = addKnob (x, y, d, ownerFilter, LDEC, "Dec", 0); }
- if (name == "sustainKnob"){ sustainKnob = addKnob (x, y, d, ownerFilter, LSUS, "Sus", 1); }
- if (name == "releaseKnob"){ releaseKnob = addKnob (x, y, d, ownerFilter, LREL, "Rel", 0); }
+ if (name == "filterKeyFollowButton"){
+ filterKeyFollowButton = addButton (x, y, w, h, ownerFilter, FLT_KF, "Key");
+ mappingComps["filterKeyFollowButton"] = filterKeyFollowButton;
+ }
+ if (name == "unisonButton"){
+ unisonButton = addButton (x, y, w, h, ownerFilter, UNISON, "Uni");
+ mappingComps["unisonButton"] = unisonButton;
+ }
- if (name == "fattackKnob"){ fattackKnob = addKnob (x, y, d, ownerFilter, FATK, "Atk", 0); }
- if (name == "fdecayKnob"){ fdecayKnob = addKnob (x, y, d, ownerFilter, FDEC, "Dec", 0); }
- if (name == "fsustainKnob"){ fsustainKnob = addKnob (x, y, d, ownerFilter, FSUS, "Sus", 1); }
- if (name == "freleaseKnob"){ freleaseKnob = addKnob (x, y, d, ownerFilter, FREL, "Rel", 0); }
+ if (name == "tuneKnob"){
+ tuneKnob = addKnob (x, y, d, ownerFilter, TUNE, "Tune", 0.5);
+ mappingComps["tuneKnob"] = tuneKnob;
+ }
+ if (name == "transposeKnob"){
+ transposeKnob = addKnob (x, y, d, ownerFilter, OCTAVE, "Transpose", 0.5);
+ mappingComps["transposeKnob"] = transposeKnob;
+ }
- if (name == "lfoFrequencyKnob"){ lfoFrequencyKnob = addKnob (x, y, d, ownerFilter, LFOFREQ, "Freq", 0); }
- if (name == "lfoAmt1Knob"){ lfoAmt1Knob = addKnob (x, y, d, ownerFilter, LFO1AMT, "Pitch", 0); }
- if (name == "lfoAmt2Knob"){ lfoAmt2Knob = addKnob (x, y, d, ownerFilter, LFO2AMT, "PWM", 0); }
+ if (name == "voiceDetuneKnob"){
+ voiceDetuneKnob =addKnob (x, y, d, ownerFilter, UDET, "VoiceDet", 0);
+ mappingComps["voiceDetuneKnob"] = voiceDetuneKnob;
+ }
- if (name == "lfoSinButton"){ lfoSinButton = addButton (x, y, w, h, ownerFilter, LFOSINWAVE, "Sin"); }
- if (name == "lfoSquareButton"){ lfoSquareButton = addButton (x, y, w, h, ownerFilter, LFOSQUAREWAVE, "SQ"); }
- if (name == "lfoSHButton"){ lfoSHButton = addButton (x, y, w, h, ownerFilter, LFOSHWAVE, "S&H"); }
+ if (name == "bendLfoRateKnob"){
+ bendLfoRateKnob = addKnob (x, y, d, ownerFilter, BENDLFORATE, "ModRate", 0.4);
+ mappingComps["bendLfoRateKnob"] = bendLfoRateKnob;
+ }
+ if (name == "veloFltEnvKnob"){
+ veloFltEnvKnob = addKnob (x, y, d, ownerFilter, VFLTENV, "VFE", 0);
+ mappingComps["veloFltEnvKnob"] = veloFltEnvKnob;
+ }
+ if (name == "veloAmpEnvKnob"){
+ veloAmpEnvKnob = addKnob (x, y, d, ownerFilter, VAMPENV, "VAE", 0);
+ mappingComps["veloAmpEnvKnob"] = veloAmpEnvKnob;
+ }
+ if (name == "midiLearnButton"){
+ midiLearnButton = addButton (x, y, w, h, ownerFilter, MIDILEARN, "LEA");
+ mappingComps["midiLearnButton"] = midiLearnButton;
+ }
+ if (name == "midiUnlearnButton"){
+ midiUnlearnButton = addButton (x, y, w, h, ownerFilter, UNLEARN, "UNL");
+ mappingComps["midiUnlearnButton"] = midiUnlearnButton;
+ }
- if (name == "lfoOsc1Button"){ lfoOsc1Button = addButton (x, y, w, h, ownerFilter, LFOOSC1, "Osc1"); }
- if (name == "lfoOsc2Button"){ lfoOsc2Button = addButton (x, y, w, h, ownerFilter, LFOOSC2, "Osc2"); }
- if (name == "lfoFilterButton"){ lfoFilterButton = addButton (x, y, w, h, ownerFilter, LFOFILTER, "Filt"); }
+ if (name == "pan1Knob"){
+ pan1Knob = addKnob (x, y, d, ownerFilter, PAN1, "1", 0.5);
+ mappingComps["pan1Knob"] = pan1Knob;
+ }
+ if (name == "pan2Knob"){
+ pan2Knob = addKnob (x, y, d, ownerFilter, PAN2, "2", 0.5);
+ mappingComps["pan2Knob"] = pan2Knob;
+ }
+ if (name == "pan3Knob"){
+ pan3Knob = addKnob (x, y, d, ownerFilter, PAN3, "3", 0.5);
+ mappingComps["pan3Knob"] = pan3Knob;
+ }
+ if (name == "pan4Knob"){
+ pan4Knob = addKnob (x, y, d, ownerFilter, PAN4, "4", 0.5);
+ mappingComps["pan4Knob"] = pan4Knob;
+ }
- if (name == "lfoPwm1Button"){ lfoPwm1Button = addButton (x, y, w, h, ownerFilter, LFOPW1, "Osc1"); }
- if (name == "lfoPwm2Button"){ lfoPwm2Button = addButton (x, y, w, h, ownerFilter, LFOPW2, "Osc2"); }
+ if (name == "pan5Knob"){
+ pan5Knob = addKnob (x, y, d, ownerFilter, PAN5, "5", 0.5);
+ mappingComps["pan5Knob"] = pan5Knob;
+ }
+ if (name == "pan6Knob"){
+ pan6Knob = addKnob (x, y, d, ownerFilter, PAN6, "6", 0.5);
+ mappingComps["pan6Knob"] = pan6Knob;
+ }
+ if (name == "pan7Knob"){
+ pan7Knob = addKnob (x, y, d, ownerFilter, PAN7, "7", 0.5);
+ mappingComps["pan7Knob"] = pan7Knob;
+ }
+ if (name == "pan8Knob"){
+ pan8Knob = addKnob (x, y, d, ownerFilter, PAN8, "8", 0.5);
+ mappingComps["pan8Knob"] = pan8Knob;
+ }
- if (name == "hardSyncButton"){ hardSyncButton = addButton (x, y, w, h, ownerFilter, OSC2HS, "Sync"); }
- if (name == "osc1SawButton"){ osc1SawButton = addButton (x, y, w, h, ownerFilter, OSC1Saw, "S"); }
- if (name == "osc2SawButton"){ osc2SawButton = addButton (x, y, w, h, ownerFilter, OSC2Saw, "S"); }
+ if (name == "bendOsc2OnlyButton"){
+ bendOsc2OnlyButton = addButton (x, y, w, h, ownerFilter, BENDOSC2, "Osc2");
+ mappingComps["bendOsc2OnlyButton"] = bendOsc2OnlyButton;
+ }
+ if (name == "bendRangeButton"){
+ bendRangeButton = addButton (x, y, w, h, ownerFilter, BENDRANGE, "12");
+ mappingComps["bendRangeButton"] = bendRangeButton;
+ }
+ if (name == "asPlayedAllocButton"){
+ asPlayedAllocButton = addButton (x, y, w, h, ownerFilter, ASPLAYEDALLOCATION, "APA");
+ mappingComps["asPlayedAllocButton"] = asPlayedAllocButton;
+ }
- if (name == "osc1PulButton"){ osc1PulButton = addButton (x, y, w, h, ownerFilter, OSC1Pul, "P"); }
- if (name == "osc2PulButton"){ osc2PulButton = addButton (x, y, w, h, ownerFilter, OSC2Pul, "P"); }
-
- if (name == "pitchQuantButton"){ pitchQuantButton = addButton (x, y, w, h, ownerFilter, OSCQuantize, "Step"); }
-
- if (name == "filterBPBlendButton"){ filterBPBlendButton = addButton (x, y, w, h, ownerFilter, BANDPASS, "Bp"); }
- if (name == "fourPoleButton"){ fourPoleButton = addButton (x, y, w, h, ownerFilter, FOURPOLE, "24"); }
- if (name == "filterHQButton"){ filterHQButton = addButton (x, y, w, h, ownerFilter, FILTER_WARM, "HQ"); }
-
- if (name == "filterKeyFollowButton"){ filterKeyFollowButton = addButton (x, y, w, h, ownerFilter, FLT_KF, "Key"); }
- if (name == "unisonButton"){ unisonButton = addButton (x, y, w, h, ownerFilter, UNISON, "Uni"); }
-
- if (name == "tuneKnob"){ tuneKnob = addKnob (x, y, d, ownerFilter, TUNE, "Tune", 0.5); }
- if (name == "transposeKnob"){ transposeKnob = addKnob (x, y, d, ownerFilter, OCTAVE, "Transpose", 0.5); }
-
- if (name == "voiceDetuneKnob"){ voiceDetuneKnob =addKnob (x, y, d, ownerFilter, UDET, "VoiceDet", 0); }
-
- if (name == "bendLfoRateKnob"){ bendLfoRateKnob = addKnob (x, y, d, ownerFilter, BENDLFORATE, "ModRate", 0.4); }
- if (name == "veloFltEnvKnob"){ veloFltEnvKnob = addKnob (x, y, d, ownerFilter, VFLTENV, "VFE", 0); }
- if (name == "veloAmpEnvKnob"){ veloAmpEnvKnob = addKnob (x, y, d, ownerFilter, VAMPENV, "VAE", 0); }
- if (name == "midiLearnButton"){ midiLearnButton = addButton (x, y, w, h, ownerFilter, MIDILEARN, "LEA"); }
- if (name == "midiUnlearnButton"){ midiUnlearnButton = addButton (x, y, w, h, ownerFilter, UNLEARN, "UNL"); }
-
- if (name == "pan1Knob"){ pan1Knob = addKnob (x, y, d, ownerFilter, PAN1, "1", 0.5); }
- if (name == "pan2Knob"){ pan2Knob = addKnob (x, y, d, ownerFilter, PAN2, "2", 0.5); }
- if (name == "pan3Knob"){ pan3Knob = addKnob (x, y, d, ownerFilter, PAN3, "3", 0.5); }
- if (name == "pan4Knob"){ pan4Knob = addKnob (x, y, d, ownerFilter, PAN4, "4", 0.5); }
-
- if (name == "pan5Knob"){ pan5Knob = addKnob (x, y, d, ownerFilter, PAN5, "5", 0.5); }
- if (name == "pan6Knob"){ pan6Knob = addKnob (x, y, d, ownerFilter, PAN6, "6", 0.5); }
- if (name == "pan7Knob"){ pan7Knob = addKnob (x, y, d, ownerFilter, PAN7, "7", 0.5); }
- if (name == "pan8Knob"){ pan8Knob = addKnob (x, y, d, ownerFilter, PAN8, "8", 0.5); }
-
- if (name == "bendOsc2OnlyButton"){ bendOsc2OnlyButton = addButton (x, y, w, h, ownerFilter, BENDOSC2, "Osc2"); }
- if (name == "bendRangeButton"){ bendRangeButton = addButton (x, y, w, h, ownerFilter, BENDRANGE, "12"); }
- if (name == "asPlayedAllocButton"){ asPlayedAllocButton = addButton (x, y, w, h, ownerFilter, ASPLAYEDALLOCATION, "APA"); }
-
- if (name == "filterDetuneKnob"){ filterDetuneKnob = addKnob (x, y, d, ownerFilter, FILTERDER, "Flt", 0.2); }
- if (name == "portamentoDetuneKnob"){ portamentoDetuneKnob = addKnob (x, y, d, ownerFilter, PORTADER, "Port", 0.2); }
- if (name == "envelopeDetuneKnob"){ envelopeDetuneKnob = addKnob (x, y, d, ownerFilter, ENVDER, "Env", 0.2); }
+ if (name == "filterDetuneKnob"){
+ filterDetuneKnob = addKnob (x, y, d, ownerFilter, FILTERDER, "Flt", 0.2);
+ mappingComps["filterDetuneKnob"] = filterDetuneKnob;
+ }
+ if (name == "portamentoDetuneKnob"){
+ portamentoDetuneKnob = addKnob (x, y, d, ownerFilter, PORTADER, "Port", 0.2);
+ mappingComps["portamentoDetuneKnob"] = portamentoDetuneKnob;
+ }
+ if (name == "envelopeDetuneKnob"){
+ envelopeDetuneKnob = addKnob (x, y, d, ownerFilter, ENVDER, "Env", 0.2);
+ mappingComps["envelopeDetuneKnob"] = envelopeDetuneKnob;
+ }
if (name == "voiceSwitch"){
- //if (voiceSwitch) voiceSwitch->setVisible(false);
-#if JUCE_WINDOWS || JUCE_LINUX
- voiceSwitch = addList (x, y, w, h, ownerFilter, VOICE_COUNT, "VoiceCount", ImageCache::getFromFile(skinFolder.getChildFile("voices.png"))); }
-#else
- voiceSwitch = addList (x, y, w, h, ownerFilter, VOICE_COUNT, "VoiceCount", ImageCache::getFromFile(skinFolder.getChildFile("voices@2x.png"))); }
-#endif
+ voiceSwitch = addList (x, y, w, h, ownerFilter, VOICE_COUNT, "VoiceCount", "voices");
+ voiceSwitch->setLookAndFeel(&this->getLookAndFeel());
+ mappingComps["voiceSwitch"] = voiceSwitch;
+ }
+
if (name == "legatoSwitch"){
- //if (legatoSwitch) legatoSwitch->setVisible(false);
-#if JUCE_WINDOWS || JUCE_LINUX
- legatoSwitch = addList (x, y, w, h, ownerFilter, LEGATOMODE, "Legato", ImageCache::getFromFile(skinFolder.getChildFile("legato.png"))); }
-#else
- legatoSwitch = addList (x, y, w, h, ownerFilter, LEGATOMODE, "Legato", ImageCache::getFromFile(skinFolder.getChildFile("legato@2x.png"))); }
-#endif
+ legatoSwitch = addList (x, y, w, h, ownerFilter, LEGATOMODE, "Legato", "legato");
+
+ legatoSwitch->setLookAndFeel(&this->getLookAndFeel());
+ mappingComps["legatoSwitch"] = legatoSwitch;
+ }
+
if (name == "menu")
{
- addMenuButton (x, y, d,
-#if JUCE_WINDOWS || JUCE_LINUX
- ImageCache::getFromFile (skinFolder.getChildFile ("menu.png")));
-#else
- ImageCache::getFromFile (skinFolder.getChildFile ("menu@2x.png")));
-#endif
+ ImageButton *img = addMenuButton (x, y, d, "menu");
+ mappingComps["menu"] = img;
}
+
+ /*
+ if (name == "guisize") {
+ xScreen = x;
+ yScreen = y;
+ if (processor.getShowPresetBar()) {
+ setSize(xScreen, yScreen + 40);
+ }
+ else {
+ setSize(xScreen, yScreen);
+ }
+ }
+ */
//DBG(" Name: " << name << " X: " <setVisible(processor.getShowPresetBar());
-
-
- presetBar->setBounds(
- (xScreen - presetBar->getWidth()) / 2, yScreen, presetBar->getWidth(), presetBar->getHeight());
-
- updatePresetBar(false);
+ presetBar->leftClicked = [this](juce::Point &pos){
+ PopupMenu menu;
+ menu.setLookAndFeel(&this->getLookAndFeel());
+ for (int i = 0; i < processor.getNumPrograms(); ++i)
+ {
+ menu.addItem (i + progStart + 1,
+ processor.getProgramName (i),
+ true,
+ i == processor.getCurrentProgram());
+ }
+ int result = menu.showAt (Rectangle (pos.getX(), pos.getY(), 1, 1));
+
+ if (result >= (progStart + 1) && result <= (progStart + processor.getNumPrograms())){
+ result -= 1;
+ result -= progStart;
+ processor.setCurrentProgram (result);
+ }
+ };
+ resized();
}
// Prepare data
@@ -289,8 +568,8 @@ void ObxdAudioProcessorEditor::loadSkin (ObxdAudioProcessor& ownerFilter)
createMenu();
ownerFilter.addChangeListener (this);
-
-
+
+ scaleFactorChanged();
repaint();
}
ObxdAudioProcessorEditor::~ObxdAudioProcessorEditor()
@@ -299,6 +578,81 @@ ObxdAudioProcessorEditor::~ObxdAudioProcessorEditor()
// deleteAllChildren(); // WATCH OUT!
}
+void ObxdAudioProcessorEditor::scaleFactorChanged()
+{
+ // update background
+ const bool highResolutionDisplay = isHighResolutionDisplay();
+ const float scaleFactor = getScaleFactor();
+
+ // notify child components
+ for (int i = 0; i < getNumChildComponents(); i++)
+ {
+ ScalableComponent* object =
+ dynamic_cast(getChildComponent(i));
+
+ if (object != nullptr)
+ {
+ object->setScaleFactor(scaleFactor, highResolutionDisplay);
+ }
+
+ // update look and feel
+ CustomLookAndFeel* laf =
+ dynamic_cast(&getChildComponent(i)->getLookAndFeel());
+ if (laf != nullptr)
+ {
+ laf->setScaleFactor(scaleFactor, highResolutionDisplay);
+ }
+ }
+
+
+ // redraw everything
+ backgroundImage = getScaledImageFromCache("main", scaleFactor, highResolutionDisplay);
+
+ int width = backgroundImage.getWidth();
+ int height = backgroundImage.getHeight();
+
+
+ if (!highResolutionDisplay)
+ {
+ if (scaleFactor == 1.5f)
+ {
+ width = roundFloatToInt(width * 0.75f);
+ height = roundFloatToInt(height * 0.75f);
+
+ }
+ else if (scaleFactor == 2.0f)
+ {
+ width /= 2;
+ height /= 2;
+ }
+ } else {
+ if (scaleFactor == 1.0f) //2x image
+ {
+ width /= 2;
+ height /= 2;
+ }
+ else if (scaleFactor == 1.5f) //4x images =>150%
+ {
+ width = roundFloatToInt(width * (0.25f + 0.125f));
+ height = roundFloatToInt(height * (0.25f + 0.125f));
+
+ }
+ else if (scaleFactor == 2.0f) //4x images =>200x
+ {
+ width /= 2;
+ height /= 2;
+ }
+ }
+
+ if (processor.getShowPresetBar())
+ {
+ setSize(width, height + presetBar->getHeight());
+ presetBar->setBounds((width - presetBar->getWidth()) / 2, height, presetBar->getWidth(), presetBar->getHeight());
+ } else
+ setSize(width, height);
+}
+
+
void ObxdAudioProcessorEditor::placeLabel (int x, int y, String text)
{
Label* lab = new Label();
@@ -309,12 +663,12 @@ void ObxdAudioProcessorEditor::placeLabel (int x, int y, String text)
addAndMakeVisible (lab);
}
-ButtonList* ObxdAudioProcessorEditor::addList (int x, int y, int width, int height, ObxdAudioProcessor& filter, int parameter, String /*name*/, Image img)
+ButtonList* ObxdAudioProcessorEditor::addList (int x, int y, int width, int height, ObxdAudioProcessor& filter, int parameter, String /*name*/, String imgName)
{
#if JUCE_WINDOWS || JUCE_LINUX
- ButtonList *bl = new ButtonList (img, height);
+ ButtonList *bl = new ButtonList (imgName, height, &processor);
#else
- ButtonList *bl = new ButtonList (img, height*2);
+ ButtonList *bl = new ButtonList (imgName, height, &processor);
#endif
buttonListAttachments.add (new ButtonList::ButtonListAttachment (filter.getPluginState(),
@@ -330,11 +684,9 @@ ButtonList* ObxdAudioProcessorEditor::addList (int x, int y, int width, int heig
Knob* ObxdAudioProcessorEditor::addKnob (int x, int y, int d, ObxdAudioProcessor& filter, int parameter, String /*name*/, float defval)
{
-#if JUCE_WINDOWS || JUCE_LINUX
- Knob* knob = new Knob (ImageCache::getFromFile(skinFolder.getChildFile("knob.png")), 48);
-#else
- Knob* knob = new Knob (ImageCache::getFromFile(skinFolder.getChildFile("knob@2x.png")), 96);
-#endif
+
+ Knob* knob = new Knob ("knob", 48, &processor);
+
knobAttachments.add (new Knob::KnobAttachment (filter.getPluginState(),
filter.getEngineParameterId (parameter),
@@ -360,11 +712,8 @@ void ObxdAudioProcessorEditor::clean()
TooglableButton* ObxdAudioProcessorEditor::addButton (int x, int y, int w, int h, ObxdAudioProcessor& filter, int parameter, String name)
{
-#if JUCE_WINDOWS || JUCE_LINUX
- TooglableButton* button = new TooglableButton (ImageCache::getFromFile(skinFolder.getChildFile("button.png")));
-#else
- TooglableButton* button = new TooglableButton (ImageCache::getFromFile(skinFolder.getChildFile("button@2x.png")));
-#endif
+ TooglableButton* button = new TooglableButton ("button", &processor);
+
if (parameter != UNLEARN){
toggleAttachments.add (new AudioProcessorValueTreeState::ButtonAttachment (filter.getPluginState(),
filter.getEngineParameterId (parameter),
@@ -381,26 +730,21 @@ TooglableButton* ObxdAudioProcessorEditor::addButton (int x, int y, int w, int h
return button;
}
-
-void ObxdAudioProcessorEditor::addMenuButton (int x, int y, int d, const Image& image)
+Rectangle ObxdAudioProcessorEditor::transformBounds(int x, int y, int w, int h)
+{
+ if (getScaleFactor() == 1.0f)
+ return Rectangle(x, y, w, h);
+
+ return Rectangle(x, y, w, h).toFloat().transformedBy(AffineTransform::scale(getScaleFactor())).toNearestInt();
+}
+ImageButton* ObxdAudioProcessorEditor::addMenuButton (int x, int y, int d, String imgName)
{
- ImageButton* imageButton;
- imageButtons.add (imageButton = new ImageButton());
- imageButton->setBounds (x, y, d, d);
- imageButton->setImages (false,
- true,
- true,
- image,
- 1.0f, // menu transparency
- Colour(),
- image,
- 1.0f, // menu hover transparency
- Colour(),
- image,
- 0.3f, // menu click transparency
- Colour());
- //imageButton->addListener (this);
+ ImageMenu* imageButton = new ImageMenu(imgName, &processor);
+ imageButtons.add (imageButton);
+ imageButton->setBounds (x, y, d, d);
+
+
imageButton->onClick = [this](){
ImageButton *imageButton = this->imageButtons[0];
auto x = imageButton->getScreenX();
@@ -410,6 +754,7 @@ void ObxdAudioProcessorEditor::addMenuButton (int x, int y, int d, const Image&
resultFromMenu (pos);
};
addAndMakeVisible (imageButton);
+ return imageButton;
}
void ObxdAudioProcessorEditor::rebuildComponents (ObxdAudioProcessor& ownerFilter)
@@ -420,22 +765,30 @@ void ObxdAudioProcessorEditor::rebuildComponents (ObxdAudioProcessor& ownerFilte
// deleteAllChildren(); // WATCH OUT!
- setSize (1440, 450);
+ setSize (1440, 450);
ownerFilter.addChangeListener (this);
repaint();
+
}
void ObxdAudioProcessorEditor::createMenu ()
{
popupMenus.clear();
PopupMenu* menu = new PopupMenu();
+ //menu->setLookAndFeel(new CustomLookAndFeel(&this->processor));
PopupMenu progMenu;
PopupMenu bankMenu;
PopupMenu skinMenu;
PopupMenu fileMenu;
- PopupMenu viewMenu;
+ //PopupMenu viewMenu;
PopupMenu midiMenu;
+ menu->setLookAndFeel(&this->getLookAndFeel());
+ progMenu.setLookAndFeel(&this->getLookAndFeel());
+ bankMenu.setLookAndFeel(&this->getLookAndFeel());
+ skinMenu.setLookAndFeel(&this->getLookAndFeel());
+ fileMenu.setLookAndFeel(&this->getLookAndFeel());
+ midiMenu.setLookAndFeel(&this->getLookAndFeel());
skins = processor.getSkinFiles();
banks = processor.getBankFiles();
{
@@ -504,6 +857,8 @@ void ObxdAudioProcessorEditor::createMenu ()
menu->addSubMenu("Programs", progMenu);
}
+
+ menu->addItem(progStart + 1000, "Preset Bar", true, processor.showPresetBar);
{
const String currentBank = processor.getCurrentBankFile().getFileName();
@@ -519,6 +874,7 @@ void ObxdAudioProcessorEditor::createMenu ()
menu->addSubMenu ("Banks", bankMenu);
}
+
{
for (int i = 0; i < skins.size(); ++i)
@@ -533,12 +889,32 @@ void ObxdAudioProcessorEditor::createMenu ()
menu->addSubMenu ("Themes", skinMenu);
// About // menu.addItem(1, String("Release ") + String(JucePlugin_VersionString).dropLastCharacters(2), false);
}
- viewMenu.addItem(progStart + 1000, "Preset Bar", true, processor.showPresetBar);
- menu->addSubMenu ("View", viewMenu);
+
+ //menu->addSubMenu ("View", viewMenu);
menuMidiNum = progStart +2000;
createMidi(menuMidiNum, midiMenu);
menu->addSubMenu ("MIDI", midiMenu);
popupMenus.add (menu);
+
+ PopupMenu scaleMenu;
+ menuScaleNum =progStart +2000 + 3000;
+ scaleMenu.addItem(menuScaleNum, "1x", true, getScaleFactor() == 1.0f);
+ scaleMenu.addItem(menuScaleNum+1, "1.5x", true, getScaleFactor() == 1.5f);
+ scaleMenu.addItem(menuScaleNum+2, "2x", true, getScaleFactor() == 2.0f);
+ menu->addSubMenu("GUI Size", scaleMenu, true);
+
+#ifdef LINUX
+ menu->addItem(1, String("Release ") + String(JucePlugin_VersionString).dropLastCharacters(2), false);
+#endif
+
+#if defined(JUCE_MAC) || defined(WIN32)
+ PopupMenu helpMenu;
+ helpMenu.setLookAndFeel(&this->getLookAndFeel());
+ String version = String("Release ") + String(JucePlugin_VersionString).dropLastCharacters(2);
+ helpMenu.addItem(menuScaleNum+4, "Manual", true);
+ helpMenu.addItem(menuScaleNum+3, version, false);
+ menu->addSubMenu("Help", helpMenu, true);
+#endif
}
void ObxdAudioProcessorEditor::createMidi(int menuNo, PopupMenu &menuMidi) {
@@ -610,16 +986,16 @@ void ObxdAudioProcessorEditor::resultFromMenu (const Point pos)
const File bankFile = banks.getUnchecked (result);
processor.loadFromFXBFile (bankFile);
- clean();
- loadSkin (processor);
+ //clean();
+ //loadSkin (processor); // Check this
}
else if (result >= (progStart + 1) && result <= (progStart + processor.getNumPrograms()))
{
result -= 1;
result -= progStart;
processor.setCurrentProgram (result);
- clean();
- loadSkin (processor);
+ //clean();
+ //loadSkin (processor); // Check this
}
else if (result < progStart){
MenuActionCallback(result);
@@ -627,7 +1003,26 @@ void ObxdAudioProcessorEditor::resultFromMenu (const Point pos)
else if (result == progStart + 1000){
processor.setShowPresetBar(!processor.getShowPresetBar());
//createMenu();
- updatePresetBar();
+ updatePresetBar(true);
+ }
+ else if (result >= menuScaleNum){
+
+ if (result ==menuScaleNum){
+ ScalableComponent::setScaleFactor(1.0f, isHighResolutionDisplay());
+ processor.setGuiSize(1);
+ }
+ else if (result == menuScaleNum+1){
+ ScalableComponent::setScaleFactor(1.5f, isHighResolutionDisplay());
+ processor.setGuiSize(2);
+ }
+ else if (result == menuScaleNum+2) {
+ ScalableComponent::setScaleFactor(2.0f, isHighResolutionDisplay());
+ processor.setGuiSize(4);
+ }
+ else if (result == menuScaleNum+4) {
+ File manualFile = processor.getDocumentFolder().getChildFile("OB-Xd Manual.pdf");
+ openInPdf(manualFile);
+ }
}
else if (result >= menuMidiNum){
unsigned int selected_idx = result - menuMidiNum;
@@ -649,18 +1044,18 @@ void ObxdAudioProcessorEditor::updatePresetBar(bool resize){
if (processor.getShowPresetBar()) {
if (resize) {
- this->setSize(this->getWidth(), this->getHeight() + 40);
+ this->setSize(this->getWidth(), this->getHeight() + presetBar->getHeight());
}
presetBar->setVisible(true);
+ presetBar->update();
+ presetBar->setBounds((getWidth() - presetBar->getWidth()) / 2, getHeight() -presetBar->getHeight(), presetBar->getWidth(), presetBar->getHeight());
}
else if (presetBar->isVisible()) {
if (resize) {
- this->setSize(this->getWidth(), this->getHeight() - 40);
+ this->setSize(this->getWidth(), this->getHeight() - presetBar->getHeight());
}
presetBar->setVisible(false);
}
- presetBar->update();
-
}
void ObxdAudioProcessorEditor::MenuActionCallback(int action){
@@ -841,9 +1236,9 @@ void ObxdAudioProcessorEditor::nextProgram() {
needNotifytoHost = true;
countTimer = 0;
-
- clean();
- loadSkin (processor);
+// Define for win and mac?
+ //clean();
+ //loadSkin (processor); // check
}
void ObxdAudioProcessorEditor::prevProgram() {
int cur = processor.getCurrentProgram() - 1;
@@ -855,8 +1250,8 @@ void ObxdAudioProcessorEditor::prevProgram() {
needNotifytoHost = true;
countTimer = 0;
- clean();
- loadSkin (processor);
+ //clean();
+ //loadSkin (processor);
}
void ObxdAudioProcessorEditor::buttonClicked (Button* b)
{
@@ -925,9 +1320,38 @@ void ObxdAudioProcessorEditor::mouseUp (const MouseEvent& e)
}
}
+
+void ObxdAudioProcessorEditor::handleAsyncUpdate() {
+ scaleFactorChanged();
+ repaint();
+}
+
void ObxdAudioProcessorEditor::paint(Graphics& g)
{
+
+ const float newPhysicalPixelScaleFactor =
+ g.getInternalContext().getPhysicalPixelScaleFactor();
+
+ if (newPhysicalPixelScaleFactor != processor.physicalPixelScaleFactor)
+ {
+ processor.physicalPixelScaleFactor = newPhysicalPixelScaleFactor;
+ scaleFactorChanged();
+ }
+
g.fillAll (Colours::black);
+
+ // background gui
+ if(processor.showPresetBar){
+ g.drawImage(backgroundImage,
+ 0, 0, getWidth(), getHeight() - 40,
+ 0, 0, backgroundImage.getWidth(), backgroundImage.getHeight());
+ } else {
+ g.drawImage(backgroundImage,
+ 0, 0, getWidth(), getHeight(),
+ 0, 0, backgroundImage.getWidth(), backgroundImage.getHeight());
+ }
+
+ /*
#if JUCE_WINDOWS || JUCE_LINUX
const File mainFile(skinFolder.getChildFile("main.png"));
#else
@@ -960,6 +1384,7 @@ void ObxdAudioProcessorEditor::paint(Graphics& g)
0, 0, image.getWidth(), image.getHeight(),
0, 0, image.getWidth(), image.getHeight());
}
+ */
}
diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h
old mode 100755
new mode 100644
index e39564c..06e20ae
--- a/Source/PluginEditor.h
+++ b/Source/PluginEditor.h
@@ -19,6 +19,7 @@
#include "Gui/ButtonList.h"
#include "Components/SetPresetNameWindow.h"
#include "Components/PresetBar.h"
+#include "Components/ScaleComponent.h"
enum KeyPressCommandIDs
{
buttonNextProgram = 1,
@@ -49,6 +50,7 @@ enum MenuAction
*/
class ObxdAudioProcessorEditor : public AudioProcessorEditor
// , public AudioProcessorListener
+ , public AsyncUpdater
, public ChangeListener
// , public Slider::Listener
, public Button::Listener
@@ -56,6 +58,7 @@ class ObxdAudioProcessorEditor : public AudioProcessorEditor
, public ApplicationCommandTarget
, public Timer
, public FileDragAndDropTarget
+ , public ScalableComponent
{
public:
@@ -65,10 +68,13 @@ public:
bool isInterestedInFileDrag(const StringArray& files) override;
void filesDropped(const StringArray& files, int x, int y) override;
+ void scaleFactorChanged() override;
+
void mouseUp (const MouseEvent& e) override;
void paint (Graphics& g) override;
void updateFromHost();
+ void handleAsyncUpdate() override;
String getCurrentProgramName(){
return processor.getProgramName(processor.getCurrentProgram());
}
@@ -166,12 +172,18 @@ public:
void deleteBank();
void resized() override;
+
+ bool isHighResolutionDisplay() const
+ {
+ return processor.physicalPixelScaleFactor > 1.0;
+ }
private:
+ Rectangle transformBounds(int x, int y, int w, int h);
Knob* addKnob (int x, int y, int d, ObxdAudioProcessor& filter, int parameter, String name, float defval);
void placeLabel (int x, int y, String text);
TooglableButton* addButton (int x, int y, int w, int h, ObxdAudioProcessor& filter, int parameter, String name);
- ButtonList* addList(int x, int y, int w, int h, ObxdAudioProcessor& filter, int parameter, String name, Image img);
- void addMenuButton (int x, int y, int d, const Image&);
+ ButtonList* addList(int x, int y, int w, int h, ObxdAudioProcessor& filter, int parameter, String name, String nameImg);
+ ImageButton* addMenuButton (int x, int y, int d, String nameImg);
void createMenu ();
void createMidi(int, PopupMenu &);
void resultFromMenu (const Point);
@@ -181,8 +193,12 @@ private:
void rebuildComponents (ObxdAudioProcessor&);
void loadSkin(ObxdAudioProcessor&);
//==============================================================================
+public:
ObxdAudioProcessor& processor;
-
+private:
+ // images
+ Image backgroundImage;
+ std::map mappingComps;
//==============================================================================
Knob* cutoffKnob=nullptr,
*resonanceKnob=nullptr,
@@ -285,6 +301,7 @@ private:
Array midiFiles;
int menuMidiNum;
+ int menuScaleNum;
int countTimerForLed = 0;
};
diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp
old mode 100755
new mode 100644
index 4547608..c8380a5
--- a/Source/PluginProcessor.cpp
+++ b/Source/PluginProcessor.cpp
@@ -69,8 +69,9 @@ ObxdAudioProcessor::ObxdAudioProcessor()
options.storageFormat = PropertiesFile::storeAsXML;
options.millisecondsBeforeSaving = 2500;
options.processLock = &configLock;
- config = std::unique_ptr (new PropertiesFile (getDocumentFolder().getChildFile ("Skin.xml"), options));
+ config = std::unique_ptr (new PropertiesFile (getDocumentFolder().getChildFile ("Skin.xml"), options));
showPresetBar = config->getBoolValue("presetnavigation");
+ gui_size = config->getIntValue("gui_size", 1);
currentSkin = config->containsKey("skin") ? config->getValue("skin") : "Ilkka Rosma Dark";
currentBank = "000 - FMR OB-Xa Patch Book";
@@ -408,6 +409,8 @@ void ObxdAudioProcessor::setStateInformation(const void* data, int sizeInBytes)
#else
std::unique_ptr xmlState = getXmlFromBinary(data, sizeInBytes);
#endif
+
+ DBG(" XML:" << xmlState->toString());
if (xmlState)
{
XmlElement* xprogs = xmlState->getFirstChildElement();
@@ -802,6 +805,7 @@ File ObxdAudioProcessor::getPresetsFolder() const
File ObxdAudioProcessor::getCurrentSkinFolder() const
{
+ DBG(" SKIN : " << currentSkin);
return getSkinFolder().getChildFile(currentSkin);
}
@@ -813,6 +817,11 @@ void ObxdAudioProcessor::setCurrentSkinFolder(const String& folderName)
config->setNeedsToBeSaved(true);
}
+void ObxdAudioProcessor::setGuiSize(const int gui_size) {
+ this->gui_size = gui_size;
+ config->setValue("gui_size", gui_size);
+ config->setNeedsToBeSaved(true);
+}
//==============================================================================
String ObxdAudioProcessor::getEngineParameterId (size_t index)
{
diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h
old mode 100755
new mode 100644
index 005dc14..cbb0d5f
--- a/Source/PluginProcessor.h
+++ b/Source/PluginProcessor.h
@@ -195,7 +195,7 @@ public:
File getCurrentSkinFolder() const;
void setCurrentSkinFolder(const String& folderName);
-
+ void setGuiSize(const int gui_size);
//==============================================================================
static String getEngineParameterId (size_t);
int getParameterIndexFromId (String);
@@ -229,8 +229,11 @@ private:
SynthEngine synth;
ObxdBank programs;
- String currentSkin;
+
public:
+ float physicalPixelScaleFactor;
+ int gui_size;
+ String currentSkin;
String currentBank;
File currentBankFile;
void saveBank();
diff --git a/Source/Utils.cpp b/Source/Utils.cpp
new file mode 100644
index 0000000..fbecca8
--- /dev/null
+++ b/Source/Utils.cpp
@@ -0,0 +1,15 @@
+#pragma once
+#include "Utils.h"
+
+void openInPdf(const File& file)
+{
+ if (file.existsAsFile()) {
+
+ file.startAsProcess();
+
+ }
+ else {
+
+ NativeMessageBox::showMessageBox(AlertWindow::WarningIcon, "Error", "OB-Xd Manual.pdf not found.");
+ }
+}
diff --git a/Source/Utils.h b/Source/Utils.h
new file mode 100644
index 0000000..df8d7b7
--- /dev/null
+++ b/Source/Utils.h
@@ -0,0 +1,3 @@
+#pragma once
+#include "../JuceLibraryCode/JuceHeader.h"
+void openInPdf(const File& file);
\ No newline at end of file