Compare commits
50 Commits
e48012e1c1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bed8cae617 | |||
| 0448355401 | |||
| ce9b7c39ec | |||
| 5fe9d7cada | |||
| ca861f1530 | |||
| 468e7974be | |||
| a507916f1c | |||
| 306c8755eb | |||
| b176c11cc1 | |||
| 1d247fc0ed | |||
| 46c08009de | |||
| 9f9f667a86 | |||
| f55522f03c | |||
| 8265ba0f0a | |||
| 6dc72353d7 | |||
| 4fb5a899d4 | |||
| b5b792b449 | |||
| 8f9e5257f6 | |||
| bfd5b41e93 | |||
| 2bb807aca9 | |||
| 4ed2a6d3aa | |||
| bda08dab84 | |||
| ba5f1a6ace | |||
| 6269e6f9f6 | |||
| 24a60d7745 | |||
| 692da4b3f2 | |||
| 6f0e1e3e5e | |||
| 27ea7f2504 | |||
| f0237bbb7e | |||
| 899c065eb0 | |||
| 134d9aa8e4 | |||
| 813f8d3a35 | |||
| d82c3921d7 | |||
| df52042972 | |||
| 31ae63b594 | |||
| b960bcbd7f | |||
| 3eae3a7cf6 | |||
| 06006194a8 | |||
| 043c847801 | |||
| 0719a092dc | |||
| 082126d3c5 | |||
| f7a9f790cf | |||
| 3963f404f6 | |||
| 7890c91bd7 | |||
| 958eec2aa0 | |||
| f363e303e5 | |||
| 9febfbf792 | |||
| 2279af9159 | |||
| f7c8df5cfc | |||
| 65d997fb78 |
0
__init__.py
Executable file
0
__init__.py
Executable file
26
athmos.py
Executable file
26
athmos.py
Executable file
@ -0,0 +1,26 @@
|
||||
from .fonts import *
|
||||
from .colors import *
|
||||
from .item_selection import ItemSelection
|
||||
import pygame
|
||||
|
||||
class Athmos(ItemSelection):
|
||||
|
||||
def __init__(self, screen):
|
||||
self.screen = screen
|
||||
self.show_list = True
|
||||
self.max_name_width = 350
|
||||
super().__init__(self.max_name_width)
|
||||
self.current_duration = 0
|
||||
self.time_started = 0
|
||||
|
||||
def set_filenames(self,filenames):
|
||||
super().set_items(filenames)
|
||||
|
||||
def get_name_by_index(self, index):
|
||||
return self.items[index]
|
||||
|
||||
def update(self):
|
||||
if self.show_list:
|
||||
super().update()
|
||||
self.screen.blit(self.surface, ((self.screen.get_width()-self.max_name_width)/2,
|
||||
(self.screen.get_height() - self.surface.get_height())/2))
|
||||
40
beatplayer.py
Normal file
40
beatplayer.py
Normal file
@ -0,0 +1,40 @@
|
||||
from .item_selection import ItemSelection
|
||||
import pygame
|
||||
from .colors import *
|
||||
from .fonts import *
|
||||
|
||||
class BeatPlayer:
|
||||
|
||||
def __init__(self, screen):
|
||||
self.screen = screen
|
||||
self.max_name_width = 200
|
||||
self.clip_selection = ItemSelection(self.max_name_width)
|
||||
self.track_selection = ItemSelection(self.max_name_width)
|
||||
self.show_selection = False
|
||||
|
||||
def set_clip_names(self, clips):
|
||||
self.clip_selection.set_items(clips)
|
||||
|
||||
def set_track_names(self, tracks):
|
||||
self.track_selection.set_items(tracks)
|
||||
|
||||
def update(self):
|
||||
if self.show_selection:
|
||||
self.track_selection.update()
|
||||
self.clip_selection.update()
|
||||
self.screen.blit(self.track_selection.surface, ((self.screen.get_width()/4),
|
||||
(self.screen.get_height() - self.track_selection.surface.get_height())/2))
|
||||
self.screen.blit(self.clip_selection.surface, ((self.screen.get_width()/4 + self.max_name_width) + 100,
|
||||
(self.screen.get_height() - self.clip_selection.surface.get_height())/2))
|
||||
else:
|
||||
selected_track = self.track_selection.get_selected_item()
|
||||
selected_clip = self.clip_selection.get_selected_item()
|
||||
if len(selected_track) > 15: selected_track = selected_track[0:13] + '...'
|
||||
if len(selected_clip) > 30: selected_clip = selected_clip[0:28] + '...'
|
||||
track_surface = font_helvetica16.render(f"{selected_track}",
|
||||
False, color_primary_dark)
|
||||
clip_surface = font_helvetica16.render(f"/ {selected_clip}",
|
||||
False, color_primary_dark)
|
||||
self.screen.blit(clip_surface, (self.screen.get_width()/2, 15))
|
||||
self.screen.blit(track_surface, (self.screen.get_width()/2-track_surface.get_width()-10, 15))
|
||||
|
||||
30
binary_button.py
Normal file
30
binary_button.py
Normal file
@ -0,0 +1,30 @@
|
||||
import pygame
|
||||
from .fonts import *
|
||||
from .colors import *
|
||||
|
||||
class BinaryButton:
|
||||
|
||||
def __init__(self, screen, position, size, label, state):
|
||||
self.screen = screen
|
||||
self.position = position
|
||||
self.size = size
|
||||
self.label = label
|
||||
self.state = state
|
||||
|
||||
def check_click(self, pos):
|
||||
if pos[0] >= self.position[0] and pos[1] >= self.position[1] and pos[0] <= self.position[0] + self.size[0] and pos[1] <= self.position[1] + self.size[1]:
|
||||
self.state = not self.state
|
||||
|
||||
def display(self):
|
||||
if self.state:
|
||||
w = 0
|
||||
text_color = "black"
|
||||
else:
|
||||
w = 2
|
||||
text_color = color_primary
|
||||
|
||||
pygame.draw.rect(self.screen, color_primary, (self.position, self.size), w)
|
||||
|
||||
label = font_helvetica16.render(self.label, False, text_color)
|
||||
self.screen.blit(label, (self.position[0] + (self.size[0] - label.get_width())/2,
|
||||
self.position[1] + (self.size[1] - label.get_height())/2))
|
||||
65
circle_button.py
Normal file
65
circle_button.py
Normal file
@ -0,0 +1,65 @@
|
||||
import pygame
|
||||
from .colors import *
|
||||
import math
|
||||
|
||||
class CircleButton:
|
||||
|
||||
def __init__(self, gui, position, radius):
|
||||
self.surface = gui.screen
|
||||
self.position = position
|
||||
self.radius = radius
|
||||
self.color = color_primary
|
||||
|
||||
def check_click(self, pos):
|
||||
if math.sqrt(math.pow(pos[0] - self.position[0], 2) +
|
||||
math.pow(pos[1] - self.position[1], 2)) < self.radius:
|
||||
self.on_click()
|
||||
|
||||
def on_click(self):
|
||||
pass
|
||||
|
||||
def draw(self):
|
||||
pass
|
||||
|
||||
def display(self):
|
||||
pygame.draw.circle(self.surface, self.color, self.position, self.radius)
|
||||
self.draw()
|
||||
|
||||
class BeatButton(CircleButton):
|
||||
|
||||
def __init__(self, gui, position, radius):
|
||||
self.playing = False
|
||||
super().__init__(gui, position, radius)
|
||||
|
||||
def on_click(self):
|
||||
self.playing = not self.playing
|
||||
|
||||
def draw(self):
|
||||
x, y = self.position
|
||||
pygame.draw.polygon(self.surface, "black", [
|
||||
(x-self.radius/2.5, y-self.radius/1.5),
|
||||
(x+self.radius/1.5, y),
|
||||
(x-self.radius/2.5, y+self.radius/1.5)
|
||||
], 2 if self.playing else 0)
|
||||
|
||||
class LoopButton(CircleButton):
|
||||
def __init__(self, gui, position, radius):
|
||||
self.state = False
|
||||
self.counter = 0
|
||||
self.frame_threshold = 30
|
||||
self.recording = False
|
||||
super().__init__(gui, position, radius)
|
||||
|
||||
def on_click(self):
|
||||
self.recording = not self.recording
|
||||
self.state = not self.state
|
||||
|
||||
def draw(self):
|
||||
pygame.draw.circle(self.surface, "black", self.position, self.radius/1.5)
|
||||
pygame.draw.circle(self.surface, self.color, self.position, self.radius/2,
|
||||
2 if not self.state else 0)
|
||||
if self.recording:
|
||||
if self.counter == self.frame_threshold:
|
||||
self.state = not self.state
|
||||
self.counter = 0
|
||||
self.counter += 1
|
||||
4
colors.py
Normal file
4
colors.py
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
color_primary = (0, 190, 180)
|
||||
color_primary_light = (0, 255, 245)
|
||||
color_primary_dark = (0, 120, 115)
|
||||
34
exit
Normal file
34
exit
Normal file
@ -0,0 +1,34 @@
|
||||
usage: git diff [<options>] [<commit>] [--] [<path>...]
|
||||
or: git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>...]
|
||||
or: git diff [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...]
|
||||
or: git diff [<options>] <commit>...<commit> [--] [<path>...]
|
||||
or: git diff [<options>] <blob> <blob>
|
||||
or: git diff [<options>] --no-index [--] <path> <path>
|
||||
|
||||
common diff options:
|
||||
-z output diff-raw with lines terminated with NUL.
|
||||
-p output patch format.
|
||||
-u synonym for -p.
|
||||
--patch-with-raw
|
||||
output both a patch and the diff-raw format.
|
||||
--stat show diffstat instead of patch.
|
||||
--numstat show numeric diffstat instead of patch.
|
||||
--patch-with-stat
|
||||
output a patch and prepend its diffstat.
|
||||
--name-only show only names of changed files.
|
||||
--name-status show names and status of changed files.
|
||||
--full-index show full object name on index lines.
|
||||
--abbrev=<n> abbreviate object names in diff-tree header and diff-raw.
|
||||
-R swap input file pairs.
|
||||
-B detect complete rewrites.
|
||||
-M detect renames.
|
||||
-C detect copies.
|
||||
--find-copies-harder
|
||||
try unchanged files as candidate for copy detection.
|
||||
-l<n> limit rename attempts up to <n> paths.
|
||||
-O<file> reorder diffs according to the <file>.
|
||||
-S<string> find filepair whose only one side contains the string.
|
||||
--pickaxe-all
|
||||
show all files diff when -S is used and hit is found.
|
||||
-a --text treat all files as text.
|
||||
|
||||
6
fonts.py
Normal file
6
fonts.py
Normal file
@ -0,0 +1,6 @@
|
||||
import pygame
|
||||
|
||||
pygame.font.init()
|
||||
|
||||
font_helvetica = pygame.font.SysFont('Helvetica', 45)
|
||||
font_helvetica16 = pygame.font.SysFont('Helvetica', 22)
|
||||
52
item_selection.py
Normal file
52
item_selection.py
Normal file
@ -0,0 +1,52 @@
|
||||
from .fonts import *
|
||||
from .colors import *
|
||||
import pygame
|
||||
import math
|
||||
|
||||
class ItemSelection:
|
||||
|
||||
def __init__(self, max_item_width, max_display_count = 9):
|
||||
self.index = 0
|
||||
self.items = []
|
||||
self.surface = pygame.Surface((0,0), pygame.SRCALPHA)
|
||||
self.max_item_width = max_item_width
|
||||
self.max_display_count = max_display_count
|
||||
self.selected_item_srf = None
|
||||
|
||||
def set_items(self, items):
|
||||
self.items = items
|
||||
self.surface = pygame.Surface(
|
||||
(self.max_item_width+50, self.get_display_count()*40), pygame.SRCALPHA)
|
||||
|
||||
def get_display_count(self):
|
||||
return min(self.max_display_count, len(self.items))
|
||||
|
||||
def get_count(self):
|
||||
return len(self.items)
|
||||
|
||||
def get_selected_item(self):
|
||||
return self.items[self.index]
|
||||
|
||||
def update(self):
|
||||
self.surface.fill("black")
|
||||
for i in range(self.get_display_count()):
|
||||
text = self.items[(i+self.index-math.floor(self.get_display_count()/2))%len(self.items)]
|
||||
if len(text)> math.floor(self.max_item_width/10):
|
||||
text = text[0:math.floor(self.max_item_width/10)-2]
|
||||
text += '...'
|
||||
#text = self.items[i]
|
||||
if i == math.floor(self.get_display_count()/2):
|
||||
#if i == self.index:
|
||||
text_surface = font_helvetica16.render(text, False, color_primary_light)
|
||||
self.selected_item_srf = text_surface
|
||||
else:
|
||||
text_surface = font_helvetica16.render(text, False, color_primary)
|
||||
opacity = -15 + math.floor((i+1) * 2 * 255 / self.max_display_count
|
||||
if i < self.max_display_count/2
|
||||
else (self.max_display_count-i) * 2 * 255 / self.max_display_count)
|
||||
text_surface.set_alpha(opacity)
|
||||
#if text_surface.get_width() > self.max_item_width: self.max_item_width = text_surface.get_width()
|
||||
self.surface.blit(text_surface, ((10, self.surface.get_height()/self.get_display_count()*i)))
|
||||
pygame.draw.rect(self.surface, color_primary_light,
|
||||
(0, self.surface.get_height()/2-25, self.max_item_width+20, 40), 2)
|
||||
|
||||
50
knob.py
50
knob.py
@ -1,31 +1,67 @@
|
||||
import pygame
|
||||
import math
|
||||
from .colors import *
|
||||
|
||||
FADE_COUNT_DOWN = 150
|
||||
|
||||
class Knob:
|
||||
|
||||
def __init__(self, screen, color, radius, position):
|
||||
self.screen = screen
|
||||
self.color = color
|
||||
def __init__(self, group, name, radius, position, value = 0):
|
||||
self.group = group
|
||||
self.name = name
|
||||
self.color = color_primary
|
||||
self.radius = radius
|
||||
self.position = position
|
||||
self.value = 0
|
||||
self.value = value
|
||||
self.focused = False
|
||||
self.count_down = FADE_COUNT_DOWN
|
||||
self.vanish_label_path = False
|
||||
self.label_path = []
|
||||
|
||||
def set_value(self, value):
|
||||
self.value = value
|
||||
self.count_down = FADE_COUNT_DOWN
|
||||
|
||||
def set_color(self, color):
|
||||
self.color = color
|
||||
|
||||
def set_focused(self, focused):
|
||||
if focused:
|
||||
self.focused = True
|
||||
self.color = color_primary_light
|
||||
else:
|
||||
self.focused = False
|
||||
self.color = color_primary
|
||||
self.count_down = FADE_COUNT_DOWN
|
||||
if not self.vanish_label_path: self.label_path = []
|
||||
|
||||
def get_position(self):
|
||||
return self.position
|
||||
|
||||
def get_index(self, knobs):
|
||||
return knobs.index(self)
|
||||
|
||||
def __eq__(self, other):
|
||||
if other is None: return False
|
||||
return self.name == other.name
|
||||
|
||||
def get_pointer_position(self):
|
||||
angle = (self.value * 0.8 * 2 + 0.7) * math.pi
|
||||
x = (self.radius - 5) * math.cos(angle) + self.position[0]
|
||||
y = (self.radius - 5) * math.sin(angle) + self.position[1]
|
||||
return(x, y)
|
||||
|
||||
def display(self):
|
||||
pygame.draw.circle(self.screen, self.color, self.position, self.radius)
|
||||
pygame.draw.line(self.screen, "black", self.position, self.get_pointer_position(), 4)
|
||||
def display(self, surface):
|
||||
m1, m2, m3 = pygame.mouse.get_pressed(3)
|
||||
if m1:
|
||||
pos = pygame.mouse.get_pos()
|
||||
if math.sqrt(math.pow(pos[0]-self.position[0],2) + math.pow(pos[1]-self.position[1],2)) < self.radius:
|
||||
self.group.set_focused(self)
|
||||
if self.focused: self.count_down -= 1
|
||||
|
||||
if self.count_down == 0:
|
||||
self.vanish_label_path = True
|
||||
self.set_focused(False)
|
||||
pygame.draw.circle(surface, self.color + (self.group.opacity,), self.position, self.radius)
|
||||
pygame.draw.line(surface, "black", self.position, self.get_pointer_position(), 4)
|
||||
|
||||
160
knobs.py
Normal file
160
knobs.py
Normal file
@ -0,0 +1,160 @@
|
||||
import pygame
|
||||
from .colors import *
|
||||
from .fonts import *
|
||||
from .knob import *
|
||||
import random
|
||||
|
||||
class Knobs:
|
||||
|
||||
def __init__(self, gui, knob_names, is_left_side=True):
|
||||
|
||||
self.gui = gui
|
||||
self.knobs_surface = pygame.Surface((gui.screenW, gui.screenH), pygame.SRCALPHA)
|
||||
|
||||
self.opacity = 0
|
||||
self.fade_speed = 5
|
||||
self.fade_in = False
|
||||
self.fade_out = False
|
||||
self.knob_names = knob_names
|
||||
|
||||
self.is_left_side = is_left_side
|
||||
|
||||
# Create and position the knobs
|
||||
self.knobs_radius = self.gui.screenW / 25
|
||||
knobs_spacing = self.knobs_radius * 2
|
||||
knobs_x = (self.gui.screenW - (self.knobs_radius + knobs_spacing) * 2) / 2
|
||||
x = knobs_x
|
||||
knobs_y = (self.gui.screenH - (self.knobs_radius + knobs_spacing) * 3) / 2
|
||||
y = knobs_y
|
||||
self.knobs = []
|
||||
for i in range(len(knob_names)):
|
||||
self.knobs.append(Knob(self, knob_names[i], self.knobs_radius, (x, y), 0))
|
||||
y += self.knobs_radius + knobs_spacing
|
||||
if i == 3 or (self.is_left_side and i == 6) or (not self.is_left_side and i == 0):
|
||||
x += self.knobs_radius + knobs_spacing
|
||||
y = knobs_y
|
||||
self.label_vanish_parameter = 0
|
||||
self.label_border_height = 0
|
||||
|
||||
def display_label(self, knob):
|
||||
if not knob.vanish_label_path: self.label_vanish_parameter = 0
|
||||
if len(knob.label_path) == 2:
|
||||
if self.label_vanish_parameter > 0:
|
||||
self.label_vanish_parameter -= 1
|
||||
elif knob.vanish_label_path: self.label_vanish_parameter = 5
|
||||
label_fx_name = font_helvetica.render(knob.name, False, color_primary_light)
|
||||
label_fx_value = font_helvetica.render('[ ' + str(int(round(knob.value * 100, 0))) + '% ]',
|
||||
False, color_primary_light)
|
||||
min_x = self.knobs[5].get_position()[0] + self.knobs_radius * 1.5
|
||||
label_x = min_x + (self.gui.screenW - min_x - label_fx_name.get_width()) / 2
|
||||
label_y = (self.gui.screenH - label_fx_name.get_height() - label_fx_value.get_height()) / 2
|
||||
|
||||
if self.label_vanish_parameter == 0:
|
||||
self.gui.label_surface.blit(label_fx_name, (label_x, label_y))
|
||||
self.gui.label_surface.blit(label_fx_value, (label_x, self.gui.screenH / 2))
|
||||
|
||||
if knob.vanish_label_path:
|
||||
if self.label_border_height < self.gui.screenH / 2:
|
||||
self.label_border_height += 2
|
||||
else: self.label_border_height = self.gui.screenH / 2
|
||||
else:
|
||||
self.label_border_height = label_y
|
||||
|
||||
pygame.draw.line(
|
||||
self.gui.label_surface,
|
||||
color_primary_dark,
|
||||
(label_x - 10, self.label_border_height),
|
||||
(label_x - 10, self.gui.screenH - self.label_border_height),
|
||||
2
|
||||
)
|
||||
|
||||
self.calculate_label_path(knob, label_x)
|
||||
|
||||
for i in range(len(knob.label_path)-1):
|
||||
pygame.draw.line(
|
||||
self.gui.label_surface,
|
||||
color_primary_dark,
|
||||
knob.label_path[i],
|
||||
knob.label_path[i+1],
|
||||
2
|
||||
)
|
||||
|
||||
def calculate_label_path(self, knob, label_x):
|
||||
if len(knob.label_path) == 0:
|
||||
knob.label_path.append(knob.get_position())
|
||||
knob_index = knob.get_index(self.knobs)
|
||||
if self.is_left_side:
|
||||
if knob_index in [0, 1, 4, 5] :
|
||||
x = knob.get_position()[0] + self.knobs_radius * 1.5
|
||||
y = knob.get_position()[1] + self.knobs_radius * 1.5
|
||||
elif knob_index in [2, 3, 6]:
|
||||
x = knob.get_position()[0] + self.knobs_radius * 1.5
|
||||
y = knob.get_position()[1] - self.knobs_radius * 1.5
|
||||
else: # knob 7
|
||||
x = knob.get_position()[0] - self.knobs_radius * 1.5
|
||||
y = knob.get_position()[1] + self.knobs_radius * 1.5
|
||||
knob.label_path.append((x, y))
|
||||
|
||||
if (knob == self.knobs[0] or knob == self.knobs[3]):
|
||||
knob.label_path.append((knob.get_position()[0] + self.knobs_radius * 1.5, self.gui.screenH/2))
|
||||
elif (knob == self.knobs[4] or knob == self.knobs[7]):
|
||||
knob.label_path.append((self.knobs[4].get_position()[0] + self.knobs_radius * 1.5, self.gui.screenH/2))
|
||||
else:
|
||||
if knob_index in [1, 2, 4, 5]:
|
||||
x = knob.get_position()[0] + self.knobs_radius * 1.5
|
||||
y = knob.get_position()[1] + self.knobs_radius * 1.5
|
||||
elif knob_index in [3, 6, 7]:
|
||||
x = knob.get_position()[0] + self.knobs_radius * 1.5
|
||||
y = knob.get_position()[1] - self.knobs_radius * 1.5
|
||||
else: # knob 0
|
||||
x = knob.get_position()[0] + self.knobs_radius * 1.5
|
||||
y = knob.get_position()[1] + self.knobs_radius * 1.5
|
||||
knob.label_path.append((x, y))
|
||||
|
||||
if (knob == self.knobs[0] or knob == self.knobs[1]):
|
||||
knob.label_path.append((knob.get_position()[0] + self.knobs_radius * 1.5, self.gui.screenH/2))
|
||||
elif (knob == self.knobs[4] or knob == self.knobs[7]):
|
||||
knob.label_path.append((knob.get_position()[0] + self.knobs_radius * 1.5, self.gui.screenH/2))
|
||||
|
||||
knob.label_path.append((label_x - 10, self.gui.screenH/2))
|
||||
|
||||
elif knob.vanish_label_path:
|
||||
if len(knob.label_path) > 1:
|
||||
p1 = list(knob.label_path[0])
|
||||
p2 = list(knob.label_path[1])
|
||||
if abs(p1[0] - p2[0]) <= 10 and abs(p1[1] - p2[1]) <= 10:
|
||||
knob.label_path.remove(tuple(p1))
|
||||
else:
|
||||
if p1[0] > p2[0]:
|
||||
p1[0] -= 10
|
||||
elif p1[0] < p2[0]:
|
||||
p1[0] += 10
|
||||
if p1[1] > p2[1]:
|
||||
p1[1] -= 10
|
||||
elif p1[1] < p2[1]:
|
||||
p1[1] += 10
|
||||
knob.label_path[0] = tuple(p1)
|
||||
else:
|
||||
knob.vanish_label_path = False
|
||||
knob.label_path = []
|
||||
|
||||
def set_focused(self, knob):
|
||||
for k in self.knobs:
|
||||
k.set_focused(k == knob)
|
||||
if knob is None:
|
||||
k.vanish_label_path = False
|
||||
|
||||
def set_value(self, index, value):
|
||||
self.set_focused(self.knobs[index])
|
||||
self.knobs[index].set_value(value)
|
||||
|
||||
def display(self):
|
||||
if self.gui.show_knobs:
|
||||
if self.fade_in and self.opacity < 255: self.opacity += self.fade_speed
|
||||
if self.fade_out and self.opacity > 0: self.opacity -= self.fade_speed
|
||||
self.knobs_surface = pygame.Surface((self.gui.screenW, self.gui.screenH), pygame.SRCALPHA)
|
||||
for knob in self.knobs:
|
||||
if knob.focused or knob.vanish_label_path: self.display_label(knob)
|
||||
knob.display(self.knobs_surface)
|
||||
|
||||
self.gui.screen.blit(self.knobs_surface, (0,0))
|
||||
41
lozenge_button.py
Normal file
41
lozenge_button.py
Normal file
@ -0,0 +1,41 @@
|
||||
import pygame
|
||||
import math
|
||||
from .colors import *
|
||||
from .fonts import *
|
||||
|
||||
class LozengeButton:
|
||||
|
||||
def __init__(self, gui, name, position, radius_x, radius_y, side):
|
||||
self.gui = gui
|
||||
self.screen = gui.screen
|
||||
self.name = name
|
||||
self.x = position[0]
|
||||
self.y = position[1]
|
||||
self.radius_x = radius_x
|
||||
self.radius_y = radius_y
|
||||
self.side = side
|
||||
self.focused = False
|
||||
|
||||
def display(self):
|
||||
m1, m2, m3 = pygame.mouse.get_pressed(3)
|
||||
if m1:
|
||||
pos = pygame.mouse.get_pos()
|
||||
if math.sqrt(math.pow(pos[0] - self.x, 2) + math.pow(pos[1] - self.y, 2)) < self.radius_y:
|
||||
self.focused = True
|
||||
self.gui.set_fx_mode_by_name(self.side, self.name)
|
||||
self.gui.set_controller_fx_mode(self.side, self.name)
|
||||
|
||||
if self.focused:
|
||||
w = 0
|
||||
fx_mode_label = font_helvetica16.render(self.name, False, color_primary_light)
|
||||
self.screen.blit(fx_mode_label, (self.x + (20 if self.side == 0 else -20-fx_mode_label.get_width()), self.y - 8))
|
||||
else:
|
||||
w = 2
|
||||
fx_mode_label = font_helvetica16.render(str(self.name)[0:1], False, color_primary_light)
|
||||
self.screen.blit(fx_mode_label, (self.x - fx_mode_label.get_width()/2 + 1,
|
||||
self.y - fx_mode_label.get_height()/2 + 1))
|
||||
pygame.draw.polygon(self.screen, color_primary_light,
|
||||
[(self.x - self.radius_x, self.y),
|
||||
(self.x, self.y - self.radius_y),
|
||||
(self.x + self.radius_x, self.y),
|
||||
(self.x, self.y + self.radius_y)], w)
|
||||
359
main.py
Normal file → Executable file
359
main.py
Normal file → Executable file
@ -1,98 +1,305 @@
|
||||
import pygame
|
||||
from knob import *
|
||||
from .colors import *
|
||||
from .fonts import *
|
||||
from .knobs import Knobs
|
||||
from .lozenge_button import LozengeButton
|
||||
from .binary_button import BinaryButton
|
||||
from .circle_button import *
|
||||
from .athmos import Athmos
|
||||
from .beatplayer import BeatPlayer
|
||||
|
||||
# pygame setup
|
||||
pygame.init()
|
||||
screenW = 561
|
||||
screenH = 325
|
||||
screen = pygame.display.set_mode((screenW, screenH))
|
||||
class GuiMain:
|
||||
|
||||
color_primary = (0, 190, 180)
|
||||
color_primary_light = (0, 255, 245)
|
||||
color_primary_dark = (0, 110, 115)
|
||||
def __init__(self, controller):
|
||||
self.controller = controller
|
||||
# pygame setup
|
||||
pygame.init()
|
||||
pygame.display.set_caption("SantoscopeUI")
|
||||
self.screen = pygame.display.set_mode((800, 480))
|
||||
#self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
|
||||
self.screenH = self.screen.get_height()
|
||||
self.screenW = self.screen.get_width()
|
||||
|
||||
# Create and position the knobs
|
||||
knobs_radius = screenW / 25
|
||||
knobs_spacing = knobs_radius * 2
|
||||
knobs_x = (screenW - (knobs_radius + knobs_spacing) * 2) / 2
|
||||
x = knobs_x
|
||||
knobs_y = (screenH - (knobs_radius + knobs_spacing) * 3) / 2
|
||||
y = knobs_y
|
||||
knobs = []
|
||||
for i in range(8):
|
||||
knobs.append(Knob(screen, color_primary, knobs_radius, (x, y)))
|
||||
y += knobs_radius + knobs_spacing
|
||||
if i == 3 or i == 6:
|
||||
x += knobs_radius + knobs_spacing
|
||||
y = knobs_y
|
||||
self.label_surface = pygame.Surface((self.screenW, self.screenH), pygame.SRCALPHA)
|
||||
|
||||
pygame.font.init() # you have to call this at the start,
|
||||
# if you want to use this module.
|
||||
font_helvetica = pygame.font.SysFont('Helvetica', 30)
|
||||
self.fx_mode_labels = [
|
||||
[
|
||||
'Strings',
|
||||
'L-Loop',
|
||||
'R-Loop',
|
||||
'Jack',
|
||||
'Athmo'
|
||||
],
|
||||
[
|
||||
'Mixer',
|
||||
'Beat'
|
||||
]
|
||||
]
|
||||
|
||||
clock = pygame.time.Clock()
|
||||
running = True
|
||||
left_knob_names = [
|
||||
'Delay Time',
|
||||
'Delay Vol',
|
||||
'Reverb Wet',
|
||||
'Reverb Size',
|
||||
'Filter Freq',
|
||||
'Distortion',
|
||||
'Detune',
|
||||
'Gain'
|
||||
]
|
||||
|
||||
def display_label(index):
|
||||
fx_label = font_helvetica.render('REVERB WET', False, color_primary_light)
|
||||
fx_value = font_helvetica.render('[ 86% ]', False, color_primary_light)
|
||||
mixer_knob_names = [
|
||||
'Jack Vol',
|
||||
'Athmo Vol',
|
||||
'Beat speed',
|
||||
'L-loop Vol',
|
||||
'-unassigned-',
|
||||
'Beat Vol',
|
||||
'R-loop Vol',
|
||||
'Master Vol'
|
||||
]
|
||||
|
||||
label_x = screenW - fx_label.get_width() - 20
|
||||
label_y = (screenH - fx_label.get_height() - fx_value.get_height()) / 2
|
||||
screen.blit(fx_label, (label_x, label_y))
|
||||
screen.blit(fx_value, (label_x, screenH / 2))
|
||||
pygame.draw.line(screen, color_primary_dark, (label_x - 10, label_y), (label_x - 10, screenH - label_y), 2)
|
||||
# Create and position the fx_mode buttons
|
||||
self.fx_mode_buttons = [[],[]]
|
||||
|
||||
line_points = []
|
||||
line_points.append(knobs[index].get_position())
|
||||
self.fx_mode = [0, 0]
|
||||
|
||||
if (index == 0 or index == 1 or index == 4 or index == 5):
|
||||
x = knobs[index].get_position()[0] + knobs_radius * 1.5
|
||||
y = knobs[index].get_position()[1] + knobs_radius * 1.5
|
||||
line_points.append((x, y))
|
||||
elif (index == 2 or index == 3 or index == 6):
|
||||
x = knobs[index].get_position()[0] + knobs_radius * 1.5
|
||||
y = knobs[index].get_position()[1] - knobs_radius * 1.5
|
||||
line_points.append((x, y))
|
||||
elif (index == 7):
|
||||
x = knobs[index].get_position()[0] - knobs_radius * 1.5
|
||||
y = knobs[index].get_position()[1] + knobs_radius * 1.5
|
||||
line_points.append((x, y))
|
||||
for i in range(len(self.fx_mode_labels[0])):
|
||||
x = self.screenW * 2.5 / 19
|
||||
y = i * self.screenH / 7.5 + 45
|
||||
r_x = self.screenW * 0.35 / 19
|
||||
r_y = (self.screenH-20) / 16
|
||||
self.fx_mode_buttons[0].append(
|
||||
LozengeButton(self, self.fx_mode_labels[0][i], (x,y), r_x, r_y, 0)
|
||||
)
|
||||
|
||||
if (index == 0 or index == 3):
|
||||
line_points.append((knobs_x + knobs_radius * 1.5, screenH/2))
|
||||
elif (index == 4 or index == 6 or index == 7):
|
||||
line_points.append((knobs[4].get_position()[0] + knobs_radius * 1.5, screenH/2))
|
||||
for i in range(len(self.fx_mode_labels[1])):
|
||||
x = self.screenW - 30
|
||||
y = i * self.screenH / 7.5 + 90
|
||||
r_x = self.screenW * 0.35 / 19
|
||||
r_y = (self.screenH-20) / 16
|
||||
self.fx_mode_buttons[1].append(
|
||||
LozengeButton(self, self.fx_mode_labels[1][i], (x,y), r_x, r_y, 1)
|
||||
)
|
||||
|
||||
line_points.append((label_x - 10, screenH/2))
|
||||
self.knobs = [[], []]
|
||||
for i in range(len(self.fx_mode_labels[0])):
|
||||
self.knobs[0].append(Knobs(self, left_knob_names))
|
||||
for i in range(len(self.fx_mode_labels[1])):
|
||||
self.knobs[1].append(Knobs(self, left_knob_names if i==1 else mixer_knob_names, is_left_side=False))
|
||||
|
||||
for i in range(len(line_points)-1):
|
||||
pygame.draw.line(screen, color_primary_dark, line_points[i], line_points[i+1], 2)
|
||||
self.set_fx_mode(0, self.fx_mode[0])
|
||||
self.set_fx_mode(1, self.fx_mode[1])
|
||||
self.show_knobs = True
|
||||
self.knobs_display_side = 0
|
||||
|
||||
knobs[index].set_value(0.86)
|
||||
knobs[index].set_color(color_primary_light)
|
||||
self.mute_button = BinaryButton(
|
||||
self.screen,
|
||||
(20, self.fx_mode_buttons[0][0].y-20),
|
||||
(40, 40), 'M',
|
||||
False)
|
||||
self.beat_button = BeatButton(self, (40, self.fx_mode_buttons[0][1].y), 20)
|
||||
self.rloop_button = LoopButton(self, (40, self.fx_mode_buttons[0][2].y), 20)
|
||||
self.lloop_button = LoopButton(self, (40, self.fx_mode_buttons[0][3].y), 20)
|
||||
|
||||
while running:
|
||||
# poll for events
|
||||
# pygame.QUIT event means the user clicked X to close your window
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
self.rec_button = BinaryButton(
|
||||
self.screen,
|
||||
(self.screenW-70, 15),
|
||||
(60, 30),
|
||||
"REC",
|
||||
False
|
||||
)
|
||||
|
||||
# fill the screen with a color to wipe away anything from last frame
|
||||
screen.fill("black")
|
||||
self.loop_input_mode = None
|
||||
self.set_loop_input_mode(0)
|
||||
|
||||
# RENDER YOUR GAME HERE
|
||||
self.beatplayer = BeatPlayer(self.screen)
|
||||
|
||||
display_label(4)
|
||||
self.athmos = Athmos(self.screen)
|
||||
self.athmos.show_list = False
|
||||
fnames = [
|
||||
"01_7Qp3xL8gK2tA5mR9eZ1vC4bN6sH0jF",
|
||||
"02_yP5cT8kL3wR0vX6mN9bQ2fZ4hJ7dS1",
|
||||
"03_3aB7eF2gH9jK5lM1nP6qR0sT8uV4B7eF2gH9jK5lM1nP6qR0sT8uV4wX",
|
||||
"04_6mV0cX8zL5jH7gF2dS9aP1oI3uY4tR",
|
||||
"05_2pQ8oR3iK6jL1fH7gK9wL0q3xZ4jL1fH7gK9wL0q3xZ4rE5",
|
||||
"06_9eZ1vC4bN6sH0jF7Qp3xL8gK2tA5mR",
|
||||
"07_0vX6mN9bQ2fZ4hJ7dS1yP5cT8kL3wR",
|
||||
"08_1nP6qR0sT8uV4wX3aB7eF2gH9jK5lM",
|
||||
"09_5jH7gF2dS9aP1oI3uY4tR6mV0cX8zL",
|
||||
"10_6jL1fH7gK9wL0q3xZ4rE5pQ8oR3iK2",
|
||||
"11_0jF7Qp3xL8gK2tA5mR9eZ1vC4bN6sH",
|
||||
"12_4hJ7dS1yP5cT8kL3wR0vX6mN9bQ2fZ",
|
||||
"13_9jK5lM1nP6qR0sT8uV4wX3aB7eF2gH"
|
||||
]
|
||||
#self.beatplayer.set_clip_names(fnames[0:5])
|
||||
#self.beatplayer.set_track_names(fnames[0:9])
|
||||
#self.set_athmo_filenames(fnames)
|
||||
self.selected_athmo_srf = None
|
||||
|
||||
for i in range(8):
|
||||
knobs[i].display()
|
||||
self.clock = pygame.time.Clock()
|
||||
self.running = True
|
||||
|
||||
pygame.draw.polygon(screen, "white", [(0, screenH/2), (screenW*3/19, screenH), (0, screenH)])
|
||||
# flip() the display to put your work on screen
|
||||
pygame.display.flip()
|
||||
def set_knob_value(self, side, index, value):
|
||||
self.knobs_display_side = side
|
||||
self.knobs[side][self.fx_mode[side]].set_value(index, value)
|
||||
|
||||
clock.tick(60) # limits FPS to 60
|
||||
def set_fx_mode(self, side, i):
|
||||
self.set_fx_mode_by_name(side, self.fx_mode_labels[side][i])
|
||||
|
||||
pygame.quit()
|
||||
def set_fx_mode_by_name(self, side, mode):
|
||||
self.knobs_display_side = side
|
||||
self.knobs[side][self.fx_mode[side]].opacity = 0 #checke
|
||||
self.fx_mode[side] = self.fx_mode_labels[side].index(mode)
|
||||
self.knobs[side][self.fx_mode[side]].set_focused(None)
|
||||
self.knobs[side][self.fx_mode[side]].fade_in = True
|
||||
for b in self.fx_mode_buttons[side]:
|
||||
b.focused = (b.name == mode)
|
||||
|
||||
def set_controller_fx_mode(self, side, mode):
|
||||
i = self.fx_mode_labels[side].index(mode)
|
||||
self.controller.set_fx_mode(side, i)
|
||||
|
||||
def show_athmos(self, show=True):
|
||||
self.athmos.show_list = show
|
||||
self.show_knobs = not show
|
||||
self.beatplayer.show_selection = False
|
||||
"""
|
||||
if show == False:
|
||||
self.set_selected_athmo()
|
||||
"""
|
||||
|
||||
def show_beatplayer(self, show=True):
|
||||
self.beatplayer.show_selection = show
|
||||
self.show_knobs = not show
|
||||
self.athmos.show_list = False
|
||||
|
||||
def set_athmo_index(self, index):
|
||||
self.athmos.index = index
|
||||
|
||||
def set_beat_clip_index(self, index):
|
||||
self.beatplayer.clip_selection.index = index
|
||||
|
||||
def set_beat_track_index(self, index):
|
||||
self.beatplayer.track_selection.index = index
|
||||
|
||||
def set_selected_athmo(self, duration):
|
||||
"""
|
||||
name = self.athmos.get_name_by_index(self.athmos.index)
|
||||
if len(name) > 20: name = name[0:22] + '...'
|
||||
self.selected_athmo_srf = font_helvetica16.render(name, False, color_primary)
|
||||
"""
|
||||
self.selected_athmo_srf = self.athmos.selected_item_srf
|
||||
self.athmos.current_duration = duration * 1000 if duration is not None else 0
|
||||
self.athmos.time_started = pygame.time.get_ticks()
|
||||
|
||||
def set_athmo_filenames(self, filenames):
|
||||
self.athmos.set_filenames(filenames)
|
||||
|
||||
def set_beat_track_names(self, names):
|
||||
self.beatplayer.set_track_names(names)
|
||||
|
||||
def set_beat_clip_names(self, names):
|
||||
self.beatplayer.set_clip_names(names)
|
||||
|
||||
def set_loop_input_mode(self, mode):
|
||||
str_mode = 'SJ'
|
||||
if mode == 0:
|
||||
str_mode = 'S'
|
||||
elif mode == 1:
|
||||
str_mode = 'J'
|
||||
self.loop_input_mode = font_helvetica16.render(str_mode, False, color_primary)
|
||||
|
||||
def update(self):
|
||||
if self.running:
|
||||
# fill the screen with a color to wipe away anything from last frame
|
||||
self.screen.fill("black")
|
||||
|
||||
self.screen.blit(self.label_surface, (0,0))
|
||||
self.label_surface = pygame.Surface((self.screenW, self.screenH), pygame.SRCALPHA)
|
||||
|
||||
self.beatplayer.update()
|
||||
self.athmos.update()
|
||||
|
||||
self.knobs[self.knobs_display_side][self.fx_mode[self.knobs_display_side]].display()
|
||||
|
||||
for i in range(2):
|
||||
for button in self.fx_mode_buttons[i]:
|
||||
button.display()
|
||||
|
||||
self.mute_button.display()
|
||||
|
||||
for i in range(1,4):
|
||||
pygame.draw.line(self.screen, color_primary_dark,
|
||||
(self.fx_mode_buttons[0][i].radius_x*0.5 + 60, self.fx_mode_buttons[0][i].y),
|
||||
(self.fx_mode_buttons[0][i].x - self.fx_mode_buttons[0][i].radius_x * 1.5,
|
||||
self.fx_mode_buttons[0][i].y))
|
||||
self.beat_button.display()
|
||||
self.lloop_button.display()
|
||||
self.rloop_button.display()
|
||||
self.rec_button.display()
|
||||
|
||||
if self.selected_athmo_srf is not None:
|
||||
self.screen.blit(self.selected_athmo_srf,
|
||||
(self.screenW*3 / 18,
|
||||
self.screenH - self.selected_athmo_srf.get_height()-10))
|
||||
|
||||
if pygame.time.get_ticks() - self.athmos.time_started >= self.athmos.current_duration:
|
||||
self.selected_athmo_srf = None
|
||||
|
||||
if self.loop_input_mode is not None:
|
||||
self.screen.blit(self.loop_input_mode,
|
||||
((self.fx_mode_buttons[0][3].x+self.lloop_button.position[0])/2-self.loop_input_mode.get_width()/2,
|
||||
(self.lloop_button.position[1]+self.rloop_button.position[1])/2-self.loop_input_mode.get_height()/2))
|
||||
|
||||
pygame.draw.polygon(self.screen, "white", [(0, self.screenH/2), (self.screenW*3 / 19, self.screenH), (0, self.screenH)])
|
||||
# flip() the display to put your work on screen
|
||||
pygame.display.flip()
|
||||
|
||||
self.clock.tick(30) # limits FPS to 60
|
||||
|
||||
for event in pygame.event.get():
|
||||
# exit when esc is pressed
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_ESCAPE:
|
||||
self.running = False
|
||||
if event.key == pygame.K_RETURN:
|
||||
if not self.beatplayer.show_selection:
|
||||
self.show_beatplayer()
|
||||
else:
|
||||
self.show_beatplayer(False)
|
||||
if event.key == pygame.K_INSERT:
|
||||
if not self.athmos.show_list:
|
||||
self.show_athmos()
|
||||
else:
|
||||
self.show_athmos(False)
|
||||
if event.key == pygame.K_UP:
|
||||
if self.athmos.show_list:
|
||||
self.athmos.index -= 1
|
||||
self.athmos.index %= self.athmos.get_count()
|
||||
else:
|
||||
self.beatplayer.clip_selection.index -= 1
|
||||
self.beatplayer.clip_selection.index %= self.beatplayer.clip_selection.get_count()
|
||||
if event.key == pygame.K_DOWN:
|
||||
if self.athmos.show_list:
|
||||
self.athmos.index += 1
|
||||
self.athmos.index %= self.athmos.get_count()
|
||||
else:
|
||||
self.beatplayer.clip_selection.index += 1
|
||||
self.beatplayer.clip_selection.index %= self.beatplayer.clip_selection.get_count()
|
||||
if event.key == pygame.K_RIGHT:
|
||||
self.beatplayer.track_selection.index += 1
|
||||
self.beatplayer.track_selection.index %= self.beatplayer.track_selection.get_count()
|
||||
if event.key == pygame.K_LEFT:
|
||||
self.beatplayer.track_selection.index -= 1
|
||||
self.beatplayer.track_selection.index %= self.beatplayer.track_selection.get_count()
|
||||
elif event.type == pygame.QUIT:
|
||||
self.running = False
|
||||
elif event.type == pygame.MOUSEBUTTONDOWN:
|
||||
if event.button == 1:
|
||||
self.mute_button.check_click(pygame.mouse.get_pos())
|
||||
self.rec_button.check_click(pygame.mouse.get_pos())
|
||||
self.beat_button.check_click(pygame.mouse.get_pos())
|
||||
self.lloop_button.check_click(pygame.mouse.get_pos())
|
||||
self.rloop_button.check_click(pygame.mouse.get_pos())
|
||||
else:
|
||||
pygame.quit()
|
||||
|
||||
Reference in New Issue
Block a user