aboutsummaryrefslogtreecommitdiff
path: root/music_sampler
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2016-07-27 22:15:25 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2016-07-27 23:08:57 +0200
commit6ebe62478a49df22c55ef6a2b1200473500a7f80 (patch)
tree20541528abe9df35592347ade1e15c005644bf58 /music_sampler
parent63ba5a8dc2aa4ec3e6f203b0ba4db249ecf0b00e (diff)
downloadMusicSampler-6ebe62478a49df22c55ef6a2b1200473500a7f80.tar.gz
MusicSampler-6ebe62478a49df22c55ef6a2b1200473500a7f80.tar.zst
MusicSampler-6ebe62478a49df22c55ef6a2b1200473500a7f80.zip
Use pip setup file1.0.0
Diffstat (limited to 'music_sampler')
-rw-r--r--music_sampler/__init__.py193
-rw-r--r--music_sampler/action.py2
-rw-r--r--music_sampler/app.py91
-rw-r--r--music_sampler/helpers.py192
-rw-r--r--music_sampler/key.py2
-rw-r--r--music_sampler/lock.py2
-rw-r--r--music_sampler/mapping.py2
-rw-r--r--music_sampler/mixer.py2
-rw-r--r--music_sampler/music_file.py2
-rw-r--r--music_sampler/music_sampler.kv900
10 files changed, 1190 insertions, 198 deletions
diff --git a/music_sampler/__init__.py b/music_sampler/__init__.py
index 4827e6c..aa551fb 100644
--- a/music_sampler/__init__.py
+++ b/music_sampler/__init__.py
@@ -1,192 +1 @@
1# -*- coding: utf-8 -*- from . import app
2import argparse
3import sys
4import os
5import math
6import sounddevice as sd
7import logging
8
9from . import sysfont
10
11class Config:
12 pass
13
14def find_font(name, style=sysfont.STYLE_NONE):
15 if getattr(sys, 'frozen', False):
16 font = sys._MEIPASS + "/fonts/{}_{}.ttf".format(name, style)
17 else:
18 font = sysfont.get_font(name, style=style)
19 if font is not None:
20 font = font[4]
21 return font
22
23def register_fonts():
24 from kivy.core.text import LabelBase
25
26 ubuntu_regular = find_font("Ubuntu", style=sysfont.STYLE_NORMAL)
27 ubuntu_bold = find_font("Ubuntu", style=sysfont.STYLE_BOLD)
28 symbola = find_font("Symbola")
29
30 if ubuntu_regular is None:
31 error_print("Font Ubuntu regular could not be found, please install it.")
32 sys.exit()
33 if symbola is None:
34 error_print("Font Symbola could not be found, please install it.")
35 sys.exit()
36 if ubuntu_bold is None:
37 warn_print("Font Ubuntu Bold could not be found.")
38
39 LabelBase.register(name="Ubuntu",
40 fn_regular=ubuntu_regular,
41 fn_bold=ubuntu_bold)
42 LabelBase.register(name="Symbola",
43 fn_regular=symbola)
44
45
46def path():
47 if getattr(sys, 'frozen', False):
48 return sys._MEIPASS + "/"
49 else:
50 path = os.path.dirname(os.path.realpath(__file__))
51 return path + "/../"
52
53def parse_args():
54 argv = sys.argv[1 :]
55 sys.argv = sys.argv[: 1]
56 if "--" in argv:
57 index = argv.index("--")
58 kivy_args = argv[index+1 :]
59 argv = argv[: index]
60
61 sys.argv.extend(kivy_args)
62
63 parser = argparse.ArgumentParser(
64 description="A Music Sampler application.",
65 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
66 parser.add_argument("-c", "--config",
67 default="config.yml",
68 required=False,
69 help="Config file to load")
70 parser.add_argument("-p", "--music-path",
71 default=".",
72 required=False,
73 help="Folder in which to find the music files")
74 parser.add_argument("-d", "--debug",
75 nargs=0,
76 action=DebugModeAction,
77 help="Print messages in console")
78 parser.add_argument("-m", "--builtin-mixing",
79 action="store_true",
80 help="Make the mixing of sounds manually\
81 (do it if the system cannot handle it correctly)")
82 parser.add_argument("-l", "--latency",
83 default="high",
84 required=False,
85 help="Latency: low, high or number of seconds")
86 parser.add_argument("-b", "--blocksize",
87 default=0,
88 type=int,
89 required=False,
90 help="Blocksize: If not 0, the number of frames to take\
91 at each step for the mixer")
92 parser.add_argument("-f", "--frame-rate",
93 default=44100,
94 type=int,
95 required=False,
96 help="Frame rate to play the musics")
97 parser.add_argument("-x", "--channels",
98 default=2,
99 type=int,
100 required=False,
101 help="Number of channels to use")
102 parser.add_argument("-s", "--sample-width",
103 default=2,
104 type=int,
105 required=False,
106 help="Sample width (number of bytes for each frame)")
107 parser.add_argument("-V", "--version",
108 action="version",
109 help="Displays the current version and exits. Only use\
110 in bundled package",
111 version=show_version())
112 parser.add_argument("--device",
113 action=SelectDeviceAction,
114 help="Select this sound device"
115 )
116 parser.add_argument("--list-devices",
117 nargs=0,
118 action=ListDevicesAction,
119 help="List available sound devices"
120 )
121 parser.add_argument('--',
122 dest="args",
123 help="Kivy arguments. All arguments after this are interpreted\
124 by Kivy. Pass \"-- --help\" to get Kivy's usage.")
125
126 from kivy.logger import Logger
127 Logger.setLevel(logging.WARN)
128
129 args = parser.parse_args(argv)
130
131 Config.yml_file = args.config
132
133 Config.latency = args.latency
134 Config.blocksize = args.blocksize
135 Config.frame_rate = args.frame_rate
136 Config.channels = args.channels
137 Config.sample_width = args.sample_width
138 Config.builtin_mixing = args.builtin_mixing
139 if args.music_path.endswith("/"):
140 Config.music_path = args.music_path
141 else:
142 Config.music_path = args.music_path + "/"
143
144class DebugModeAction(argparse.Action):
145 def __call__(self, parser, namespace, values, option_string=None):
146 from kivy.logger import Logger
147 Logger.setLevel(logging.DEBUG)
148
149class SelectDeviceAction(argparse.Action):
150 def __call__(self, parser, namespace, values, option_string=None):
151 sd.default.device = values
152
153class ListDevicesAction(argparse.Action):
154 nargs = 0
155 def __call__(self, parser, namespace, values, option_string=None):
156 print(sd.query_devices())
157 sys.exit()
158
159def show_version():
160 if getattr(sys, 'frozen', False):
161 with open(path() + ".pyinstaller_commit", "r") as f:
162 return f.read()
163 else:
164 return "option '-v' can only be used in bundled package"
165
166def duration_to_min_sec(duration):
167 minutes = int(duration / 60)
168 seconds = int(duration) % 60
169 if minutes < 100:
170 return "{:2}:{:0>2}".format(minutes, seconds)
171 else:
172 return "{}:{:0>2}".format(minutes, seconds)
173
174def gain(volume, old_volume=None):
175 if old_volume is None:
176 return 20 * math.log10(max(volume, 0.1) / 100)
177 else:
178 return [
179 20 * math.log10(max(volume, 0.1) / max(old_volume, 0.1)),
180 max(volume, 0)]
181
182def debug_print(message, with_trace=False):
183 from kivy.logger import Logger
184 Logger.debug('MusicSampler: ' + message, exc_info=with_trace)
185
186def error_print(message, with_trace=False):
187 from kivy.logger import Logger
188 Logger.error('MusicSampler: ' + message, exc_info=with_trace)
189
190def warn_print(message, with_trace=False):
191 from kivy.logger import Logger
192 Logger.warn('MusicSampler: ' + message, exc_info=with_trace)
diff --git a/music_sampler/action.py b/music_sampler/action.py
index 4b5a71d..ef56b7c 100644
--- a/music_sampler/action.py
+++ b/music_sampler/action.py
@@ -1,5 +1,5 @@
1from transitions.extensions import HierarchicalMachine as Machine 1from transitions.extensions import HierarchicalMachine as Machine
2from . import debug_print, error_print 2from .helpers import debug_print, error_print
3from . import actions 3from . import actions
4 4
5class Action: 5class Action:
diff --git a/music_sampler/app.py b/music_sampler/app.py
new file mode 100644
index 0000000..81c47a7
--- /dev/null
+++ b/music_sampler/app.py
@@ -0,0 +1,91 @@
1from .helpers import parse_args, register_fonts, duration_to_min_sec, path
2
3parse_args()
4
5import kivy
6kivy.require("1.9.1")
7from kivy.app import App
8from kivy.uix.floatlayout import FloatLayout
9from kivy.uix.relativelayout import RelativeLayout
10from kivy.properties import ListProperty, StringProperty
11from kivy.clock import Clock
12from kivy.core.window import Window
13from kivy.lang import Builder
14from .key import Key
15from .mapping import Mapping
16
17register_fonts()
18
19class KeyList(RelativeLayout):
20 keylist = ListProperty([])
21 first_key = StringProperty("")
22 second_key = StringProperty("")
23 third_key = StringProperty("")
24
25 def append(self, value):
26 self.keylist.insert(0, value)
27
28 def on_keylist(self, instance, new_key_list):
29 if len(self.keylist) > 0:
30 self.first_key = self.keylist[0]
31 if len(self.keylist) > 1:
32 self.second_key = self.keylist[1]
33 if len(self.keylist) > 2:
34 self.third_key = self.keylist[2]
35
36class PlayList(RelativeLayout):
37 playlist = ListProperty([])
38
39 def __init__(self, **kwargs):
40 super(PlayList, self).__init__(**kwargs)
41 Clock.schedule_interval(self.update_playlist, 0.5)
42
43 def update_playlist(self, dt):
44 if self.parent is None or 'Mapping' not in self.parent.ids:
45 return True
46
47 open_files = self.parent.ids['Mapping'].open_files
48 self.playlist = []
49 for music_file in open_files.values():
50 if not music_file.is_in_use():
51 continue
52
53 text = "{}/{}".format(
54 duration_to_min_sec(music_file.sound_position),
55 duration_to_min_sec(music_file.sound_duration))
56
57 if music_file.is_loaded_paused():
58 self.playlist.append(["⏸", music_file.name, text, False])
59 else:
60 self.playlist.append(["⏵", music_file.name, text, True])
61
62
63class ActionList(RelativeLayout):
64 action_title = StringProperty("")
65 action_list = ListProperty([])
66
67 def update_list(self, key, action_descriptions):
68 self.action_title = "actions linked to key {}:".format(key.key_sym)
69 self.action_list = []
70
71 for [action, status] in action_descriptions:
72 if status == "done":
73 icon = "✓"
74 elif status == "current":
75 icon = "✅"
76 else:
77 icon = " "
78 self.action_list.append([icon, action])
79
80class Screen(FloatLayout):
81 pass
82
83class MusicSamplerApp(App):
84 def build(self):
85 Window.size = (913, 563)
86
87 return Screen()
88
89def main():
90 Builder.load_file(path() + "/music_sampler.kv")
91 MusicSamplerApp().run()
diff --git a/music_sampler/helpers.py b/music_sampler/helpers.py
new file mode 100644
index 0000000..1788084
--- /dev/null
+++ b/music_sampler/helpers.py
@@ -0,0 +1,192 @@
1# -*- coding: utf-8 -*-
2import argparse
3import sys
4import os
5import math
6import sounddevice as sd
7import logging
8
9from . import sysfont
10
11class Config:
12 pass
13
14def find_font(name, style=sysfont.STYLE_NONE):
15 if getattr(sys, 'frozen', False):
16 font = sys._MEIPASS + "/fonts/{}_{}.ttf".format(name, style)
17 else:
18 font = sysfont.get_font(name, style=style)
19 if font is not None:
20 font = font[4]
21 return font
22
23def register_fonts():
24 from kivy.core.text import LabelBase
25
26 ubuntu_regular = find_font("Ubuntu", style=sysfont.STYLE_NORMAL)
27 ubuntu_bold = find_font("Ubuntu", style=sysfont.STYLE_BOLD)
28 symbola = find_font("Symbola")
29
30 if ubuntu_regular is None:
31 error_print("Font Ubuntu regular could not be found, please install it.")
32 sys.exit()
33 if symbola is None:
34 error_print("Font Symbola could not be found, please install it.")
35 sys.exit()
36 if ubuntu_bold is None:
37 warn_print("Font Ubuntu Bold could not be found.")
38
39 LabelBase.register(name="Ubuntu",
40 fn_regular=ubuntu_regular,
41 fn_bold=ubuntu_bold)
42 LabelBase.register(name="Symbola",
43 fn_regular=symbola)
44
45
46def path():
47 if getattr(sys, 'frozen', False):
48 return sys._MEIPASS + "/"
49 else:
50 return os.path.dirname(os.path.realpath(__file__))
51
52def parse_args():
53 argv = sys.argv[1 :]
54 sys.argv = sys.argv[: 1]
55 if "--" in argv:
56 index = argv.index("--")
57 kivy_args = argv[index+1 :]
58 argv = argv[: index]
59
60 sys.argv.extend(kivy_args)
61
62 parser = argparse.ArgumentParser(
63 description="A Music Sampler application.",
64 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
65 parser.add_argument("-c", "--config",
66 default="config.yml",
67 required=False,
68 help="Config file to load")
69 parser.add_argument("-p", "--music-path",
70 default=".",
71 required=False,
72 help="Folder in which to find the music files")
73 parser.add_argument("-d", "--debug",
74 nargs=0,
75 action=DebugModeAction,
76 help="Print messages in console")
77 parser.add_argument("-m", "--builtin-mixing",
78 action="store_true",
79 help="Make the mixing of sounds manually\
80 (do it if the system cannot handle it correctly)")
81 parser.add_argument("-l", "--latency",
82 default="high",
83 required=False,
84 help="Latency: low, high or number of seconds")
85 parser.add_argument("-b", "--blocksize",
86 default=0,
87 type=int,
88 required=False,
89 help="Blocksize: If not 0, the number of frames to take\
90 at each step for the mixer")
91 parser.add_argument("-f", "--frame-rate",
92 default=44100,
93 type=int,
94 required=False,
95 help="Frame rate to play the musics")
96 parser.add_argument("-x", "--channels",
97 default=2,
98 type=int,
99 required=False,
100 help="Number of channels to use")
101 parser.add_argument("-s", "--sample-width",
102 default=2,
103 type=int,
104 required=False,
105 help="Sample width (number of bytes for each frame)")
106 parser.add_argument("-V", "--version",
107 action="version",
108 help="Displays the current version and exits. Only use\
109 in bundled package",
110 version=show_version())
111 parser.add_argument("--device",
112 action=SelectDeviceAction,
113 help="Select this sound device"
114 )
115 parser.add_argument("--list-devices",
116 nargs=0,
117 action=ListDevicesAction,
118 help="List available sound devices"
119 )
120 parser.add_argument('--',
121 dest="args",
122 help="Kivy arguments. All arguments after this are interpreted\
123 by Kivy. Pass \"-- --help\" to get Kivy's usage.")
124
125 from kivy.logger import Logger
126 Logger.setLevel(logging.WARN)
127
128 args = parser.parse_args(argv)
129
130 Config.yml_file = args.config
131
132 Config.latency = args.latency
133 Config.blocksize = args.blocksize
134 Config.frame_rate = args.frame_rate
135 Config.channels = args.channels
136 Config.sample_width = args.sample_width
137 Config.builtin_mixing = args.builtin_mixing
138 if args.music_path.endswith("/"):
139 Config.music_path = args.music_path
140 else:
141 Config.music_path = args.music_path + "/"
142
143class DebugModeAction(argparse.Action):
144 def __call__(self, parser, namespace, values, option_string=None):
145 from kivy.logger import Logger
146 Logger.setLevel(logging.DEBUG)
147
148class SelectDeviceAction(argparse.Action):
149 def __call__(self, parser, namespace, values, option_string=None):
150 sd.default.device = values
151
152class ListDevicesAction(argparse.Action):
153 nargs = 0
154 def __call__(self, parser, namespace, values, option_string=None):
155 print(sd.query_devices())
156 sys.exit()
157
158def show_version():
159 if getattr(sys, 'frozen', False):
160 with open(path() + ".pyinstaller_commit", "r") as f:
161 return f.read()
162 else:
163 return "option '-v' can only be used in bundled package"
164
165def duration_to_min_sec(duration):
166 minutes = int(duration / 60)
167 seconds = int(duration) % 60
168 if minutes < 100:
169 return "{:2}:{:0>2}".format(minutes, seconds)
170 else:
171 return "{}:{:0>2}".format(minutes, seconds)
172
173def gain(volume, old_volume=None):
174 if old_volume is None:
175 return 20 * math.log10(max(volume, 0.1) / 100)
176 else:
177 return [
178 20 * math.log10(max(volume, 0.1) / max(old_volume, 0.1)),
179 max(volume, 0)]
180
181def debug_print(message, with_trace=False):
182 from kivy.logger import Logger
183 Logger.debug('MusicSampler: ' + message, exc_info=with_trace)
184
185def error_print(message, with_trace=False):
186 from kivy.logger import Logger
187 Logger.error('MusicSampler: ' + message, exc_info=with_trace)
188
189def warn_print(message, with_trace=False):
190 from kivy.logger import Logger
191 Logger.warn('MusicSampler: ' + message, exc_info=with_trace)
192
diff --git a/music_sampler/key.py b/music_sampler/key.py
index 66e792d..b05de4c 100644
--- a/music_sampler/key.py
+++ b/music_sampler/key.py
@@ -4,7 +4,7 @@ from kivy.properties import AliasProperty, BooleanProperty, \
4from kivy.uix.behaviors import ButtonBehavior 4from kivy.uix.behaviors import ButtonBehavior
5 5
6from .action import Action 6from .action import Action
7from . import debug_print 7from .helpers import debug_print
8import time 8import time
9import threading 9import threading
10from transitions.extensions import HierarchicalMachine as Machine 10from transitions.extensions import HierarchicalMachine as Machine
diff --git a/music_sampler/lock.py b/music_sampler/lock.py
index 9beafcd..5befe33 100644
--- a/music_sampler/lock.py
+++ b/music_sampler/lock.py
@@ -1,6 +1,6 @@
1import threading 1import threading
2 2
3from . import debug_print 3from .helpers import debug_print
4 4
5class Lock: 5class Lock:
6 def __init__(self, lock_type): 6 def __init__(self, lock_type):
diff --git a/music_sampler/mapping.py b/music_sampler/mapping.py
index bb20e67..ca471ef 100644
--- a/music_sampler/mapping.py
+++ b/music_sampler/mapping.py
@@ -12,7 +12,7 @@ from transitions.extensions import HierarchicalMachine as Machine
12 12
13from .music_file import MusicFile 13from .music_file import MusicFile
14from .mixer import Mixer 14from .mixer import Mixer
15from . import Config, gain, error_print, warn_print 15from .helpers import Config, gain, error_print, warn_print
16from .action import Action 16from .action import Action
17 17
18class Mapping(RelativeLayout): 18class Mapping(RelativeLayout):
diff --git a/music_sampler/mixer.py b/music_sampler/mixer.py
index 9242b61..c8ec907 100644
--- a/music_sampler/mixer.py
+++ b/music_sampler/mixer.py
@@ -2,7 +2,7 @@ import sounddevice as sd
2import audioop 2import audioop
3import time 3import time
4 4
5from . import Config 5from .helpers import Config
6 6
7sample_width = Config.sample_width 7sample_width = Config.sample_width
8 8
diff --git a/music_sampler/music_file.py b/music_sampler/music_file.py
index 2d3ba72..fa6293d 100644
--- a/music_sampler/music_file.py
+++ b/music_sampler/music_file.py
@@ -8,7 +8,7 @@ import os.path
8import audioop 8import audioop
9 9
10from .lock import Lock 10from .lock import Lock
11from . import Config, gain, debug_print, error_print 11from .helpers import Config, gain, debug_print, error_print
12from .mixer import Mixer 12from .mixer import Mixer
13from .music_effect import GainEffect 13from .music_effect import GainEffect
14 14
diff --git a/music_sampler/music_sampler.kv b/music_sampler/music_sampler.kv
new file mode 100644
index 0000000..9057532
--- /dev/null
+++ b/music_sampler/music_sampler.kv
@@ -0,0 +1,900 @@
1#:import math math
2#:import h music_sampler
3
4<Key>:
5 pad_col_sep: 0 if not self.pad_cols else self.parent.pad_x
6 pad_cols: False
7
8 y: (self.parent.top-self.parent.y) - (self.row) * self.parent.key_size - (self.row - 1) * self.parent.key_sep
9 x: (self.col - 1) * self.parent.key_size + int(self.col - 1) * self.parent.key_sep + self.pad_col_sep
10 size_hint: None, None
11 enabled: True
12 line_width: 2
13 row: 1
14 col: 0
15 key_code: 0
16 key_sym: ""
17 key_width: 1
18 key_height: 1
19 width: self.key_width * (self.parent.key_size + self.parent.key_sep) - self.parent.key_sep
20 height: self.key_height * (self.parent.key_size + self.parent.key_sep) - self.parent.key_sep
21 canvas.before:
22 Color:
23 rgba: self.color
24 RoundedRectangle:
25 pos: self.x, self.y
26 size: self.size
27 canvas:
28 Color:
29 rgba: self.line_color
30 Line:
31 rounded_rectangle: self.x + self.line_width, self.y + self.line_width, self.width - 2 * self.line_width, self.height - 2 * self.line_width, 10
32 width: self.line_width
33 Color:
34 rgba: self.line_cross_color
35 Line:
36 points: self.x + self.line_width + 3, self.y + self.line_width + 3, self.x + self.width - 2 * self.line_width - 3, self.y + self.height - 2 * self.line_width - 3
37 width: self.line_width
38 Line:
39 points: self.x + self.line_width + 3, self.y + self.height - 2 * self.line_width - 3, self.x + self.width - 2 * self.line_width - 3, self.y + self.line_width + 3
40 width: self.line_width
41 Label:
42 id: key_label
43 font_name: "Ubuntu"
44 bold: True
45 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size))
46 color: 0, 0, 0, 1
47 text: self.parent.key_sym
48 text_size: self.parent.width,self.font_size
49 shorten: True
50 shorten_from: "right"
51 split_str: ""
52 center_x: self.parent.x + self.texture_size[0] /2 + 5
53 center_y: self.parent.y + self.parent.height - self.texture_size[1] /2 - 5
54 Label:
55 id: key_description_title
56 font_name: "Ubuntu"
57 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size / 2))
58 color: 0, 0, 0, 1
59 text: self.parent.description_title
60 text_size: self.parent.width - 2*self.parent.line_width, self.font_size
61 halign: "right"
62 valign: "middle"
63 center_x: self.parent.x + self.texture_size[0] /2
64 center_y: self.parent.y + self.parent.height - self.texture_size[1] /2 - 5
65 Label:
66 id: key_description
67 font_name: "Ubuntu"
68 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size / 2))
69 color: 0, 0, 0, 1
70 text: "\n".join(self.parent.description)
71 text_size: 2 * self.parent.width,self.parent.height - key_label.font_size
72 halign: "left"
73 valign: "middle"
74 pos: self.parent.x + 2 * self.parent.line_width + 2, self.parent.y
75 size_hint: None, None
76 size: 2 * self.parent.width - 2 * self.parent.line_width, self.parent.height - key_label.font_size
77
78<Screen>:
79 canvas:
80 Color:
81 rgba: 229/255, 228/255, 226/255, 1
82 Rectangle:
83 pos: 0, 0
84 size: self.width, self.height
85
86 key_size: int( (3 * self.width - 16) / 56)
87 key_sep: int( self.key_size / 24)
88 key_pad_sep: int( self.key_size / 7) + 1
89
90 border: (self.width - self.key_size * 18 - self.key_sep * 16 - self.key_pad_sep)/ 2
91
92 mapping_height: self.key_size * 6 + self.key_sep * 5
93 mapping_width: self.key_size * 18 + self.key_sep * 16 + self.key_pad_sep
94 mapping_x: self.border
95 mapping_y: self.top - self.mapping_height - self.border
96
97 key_list_width: 4 * (mock_ubuntu_regular.width or 0)
98 key_list_height: self.height - self.mapping_height - 3 * self.border
99 key_list_x: (self.action_list_width or 0) + 2 * self.border
100 key_list_y: self.border
101
102 action_list_height: self.height - self.mapping_height - 3 * self.border
103 action_list_width: 3 * self.width / 4 - self.key_list_width - self.border
104 action_list_x: self.border
105 action_list_y: self.border
106
107 play_list_height: self.action_list_height
108 play_list_width: self.width - self.action_list_width - 3* self.border
109 play_list_y: self.border
110 play_list_x: self.action_list_width + self.key_list_width + 3 * self.border
111
112 min_height: min(mock_symbola.height, mock_ubuntu_regular.height, mock_ubuntu_bold.height)
113 symbola_line_height: self.min_height / max(mock_symbola.height,1)
114 ubuntu_regular_line_height: self.min_height / max(mock_ubuntu_regular.height,1)
115 ubuntu_bold_line_height: self.min_height / max(mock_ubuntu_bold.height,1)
116 Label:
117 id: mock_symbola
118 font_name: "Symbola"
119 font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10))
120 color: 0, 0, 0, 0
121 text: "A"
122 text_size: None, None
123 size_hint: None, None
124 size: self.texture_size
125 Label:
126 id: mock_ubuntu_regular
127 font_name: "Ubuntu"
128 font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10))
129 color: 0, 0, 0, 0
130 text: "A"
131 text_size: None, None
132 size_hint: None, None
133 size: self.texture_size
134 Label:
135 id: mock_ubuntu_bold
136 font_name: "Ubuntu"
137 bold: True
138 font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10))
139 color: 0, 0, 0, 0
140 text: "A"
141 text_size: None, None
142 size_hint: None, None
143 size: self.texture_size
144
145 Mapping:
146 id: Mapping
147 pos: self.parent.mapping_x, self.parent.mapping_y
148 size: self.parent.mapping_width, self.parent.mapping_height
149
150 key_size: self.parent.key_size
151 key_sep: self.parent.key_sep
152 key_pad_sep: self.parent.key_pad_sep
153 pad_x: self.key_size * 15 + 14 * self.key_sep + self.key_pad_sep
154 ActionList:
155 id: ActionList
156 pos: self.parent.action_list_x, self.parent.action_list_y
157 size: self.parent.action_list_width, self.parent.action_list_height
158 KeyList:
159 id: KeyList
160 pos: self.parent.key_list_x, self.parent.key_list_y
161 size: self.parent.key_list_width, self.parent.key_list_height
162 PlayList:
163 id: PlayList
164 pos: self.parent.play_list_x, self.parent.play_list_y
165 size: self.parent.play_list_width, self.parent.play_list_height
166
167<KeyList>:
168 size_hint: None, None
169 canvas:
170 Color:
171 rgba: 250./255, 250./255, 250./255, 1
172 Rectangle:
173 pos: 0, 0
174 size: self.width, self.height
175 Label:
176 id: key_list_first
177 font_name: "Ubuntu"
178 bold: True
179 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
180 color: 0, 0, 0, 1
181 text: self.parent.first_key
182 text_size: None, None
183 valign: "top"
184 halign: "center"
185 size_hint: None, None
186 size: self.parent.width, self.texture_size[1]
187 pos: 0, self.parent.height - self.height
188 Label:
189 id: key_list_second
190 font_name: "Ubuntu"
191 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
192 color: 0, 0, 0, 1
193 text: self.parent.second_key
194 text_size: None, None
195 valign: "top"
196 halign: "center"
197 size_hint: None, None
198 size: self.parent.width, self.texture_size[1]
199 pos: 0, self.parent.height - key_list_first.height - self.height
200 Label:
201 id: key_list_third
202 font_name: "Ubuntu"
203 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
204 color: 0, 0, 0, 0.75
205 text: self.parent.third_key
206 text_size: None, None
207 valign: "top"
208 halign: "center"
209 size_hint: None, None
210 size: self.parent.width, self.texture_size[1]
211 pos: 0, self.parent.height - key_list_first.height - key_list_second.height - self.height
212 Label:
213 id: key_list_rest
214 font_name: "Ubuntu"
215 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
216 color: 0, 0, 0, 0.5
217 text: "\n".join(self.parent.keylist[3:])
218 text_size: None, None
219 valign: "top"
220 halign: "center"
221 size_hint: None, None
222 size: self.parent.width, self.texture_size[1]
223 pos: 0, self.parent.height - key_list_first.height - key_list_second.height - key_list_third.height - self.height
224
225<ActionList>:
226 size_hint: None, None
227 canvas:
228 Color:
229 rgba: 250./255, 250./255, 250./255, 1
230 Rectangle:
231 pos: 0, 0
232 size: self.width, self.height
233
234 Label:
235 id: action_list_title
236 font_name: "Ubuntu"
237 bold: True
238 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
239 color: 0, 0, 0, 1
240 text: self.parent.action_title
241 text_size: None, self.parent.height
242 halign: "left"
243 valign: "top"
244 size_hint: None, None
245 size: self.texture_size[0], self.parent.height
246 Label:
247 id: action_list_icons
248 font_name: "Symbola"
249 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
250 line_height: self.parent.parent.symbola_line_height or 1
251 color: 0, 0, 0, 1
252 text: "\n".join(map(lambda x: x[0], self.parent.action_list))
253 text_size: None, self.parent.height
254 halign: "left"
255 valign: "top"
256 size_hint: None, None
257 size: self.texture_size[0], self.parent.height - 3 * self.line_height * self.font_size
258 Label:
259 id: action_list_names
260 font_name: "Ubuntu"
261 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
262 line_height: self.parent.parent.ubuntu_regular_line_height or 1
263 color: 0, 0, 0, 1
264 text: "\n".join(map(lambda x: x[1], self.parent.action_list))
265 text_size: None, self.parent.height
266 halign: "left"
267 valign: "top"
268 size_hint: None, None
269 pos: 15, self.y
270 size: self.texture_size[0], self.parent.height - 3 * self.line_height * self.font_size
271
272<PlayList>:
273 size_hint: None, None
274 canvas:
275 Color:
276 rgba: 250./255, 250./255, 250./255, 1
277 Rectangle:
278 pos: 0, 0
279 size: self.width, self.height
280
281 Label:
282 id: playlist_icons
283 font_name: "Symbola"
284 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
285 line_height: self.parent.parent.symbola_line_height or 1
286 color: 0, 0, 0, 1
287 text: "\n".join(map(lambda x: x[0], self.parent.playlist))
288 text_size: None, self.parent.height
289 halign: "left"
290 valign: "top"
291 size_hint: None, None
292 size: self.texture_size[0], self.parent.height
293 Label:
294 id: playlist_names
295 font_name: "Ubuntu" # FIXME: Mettre en gras quand c'est en cours
296 line_height: self.parent.parent.ubuntu_regular_line_height or 1
297 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
298 color: 0, 0, 0, 1
299 text: "\n".join(map(lambda x: x[1], self.parent.playlist))
300 text_size: None, self.parent.height
301 halign: "left"
302 valign: "top"
303 size_hint: None, None
304 pos: 15, self.y
305 size: self.texture_size[0], self.parent.height
306 Label:
307 canvas.before:
308 Color:
309 rgba: 250./255, 250./255, 250./255, 1
310 Rectangle:
311 pos: self.pos
312 size: self.width, self.height
313 id: playlist_times
314 font_name: "Ubuntu"
315 line_height: self.parent.parent.ubuntu_regular_line_height or 1
316 font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10))
317 color: 0, 0, 0, 1
318 text: "\n".join(map(lambda x: x[2], self.parent.playlist))
319 text_size: None, self.parent.height
320 halign: "left"
321 valign: "top"
322 size_hint: None, None
323 pos: self.parent.width - 3 * self.width / 2 - 2 * (self.parent.parent.border or 0), self.y
324 size: self.texture_size[0], self.parent.height
325
326<Mapping>:
327 size_hint: None, None
328 key_size: 48
329 key_sep: 2
330 key_pad_sep: 7
331 pad_x: 755
332 canvas:
333 Color:
334 rgba: 250./255, 250./255, 250./255, 1
335 Rectangle:
336 pos: 0, 0
337 size: self.width, self.height
338 Color:
339 rgba: self.ready_color
340 Ellipse:
341 pos: self.width - self.key_size / 2, self.height - self.key_size /2
342 size: self.key_size / 3, self.key_size / 3
343 Label:
344 font_name: "Ubuntu"
345 font_size: math.ceil(2 * math.sqrt(self.parent.key_size or 10))
346 color: 0, 0, 0, 1
347 text: "volume: {}%".format(self.parent.master_volume)
348 valign: "top"
349 size_hint: None, None
350 size: self.texture_size[0], self.texture_size[1]
351 x: self.parent.width - self.width - 2 * self.parent.key_size / 3
352 center_y: self.parent.height - self.height
353 Key:
354 id: Key_27
355 key_code: 27
356 key_sym: "ESC"
357 row: 1
358 col: 1
359 Key:
360 id: Key_282
361 key_code: 282
362 key_sym: "F1"
363 row: 1
364 col: 3
365 Key:
366 id: Key_283
367 key_code: 283
368 key_sym: "F2"
369 row: 1
370 col: 4
371 Key:
372 id: Key_284
373 key_code: 284
374 key_sym: "F3"
375 row: 1
376 col: 5
377 Key:
378 id: Key_285
379 key_code: 285
380 key_sym: "F4"
381 row: 1
382 col: 6
383
384 Key:
385 id: Key_286
386 key_code: 286
387 key_sym: "F5"
388 row: 1
389 col: 7.5
390 Key:
391 id: Key_287
392 key_code: 287
393 key_sym: "F6"
394 row: 1
395 col: 8.5
396 Key:
397 id: Key_288
398 key_code: 288
399 key_sym: "F7"
400 row: 1
401 col: 9.5
402 Key:
403 id: Key_289
404 key_code: 289
405 key_sym: "F8"
406 row: 1
407 col: 10.5
408
409 Key:
410 id: Key_290
411 key_code: 290
412 key_sym: "F9"
413 row: 1
414 col: 12
415 Key:
416 id: Key_291
417 key_code: 291
418 key_sym: "F10"
419 row: 1
420 col: 13
421 Key:
422 id: Key_292
423 key_code: 292
424 key_sym: "F11"
425 row: 1
426 col: 14
427 Key:
428 id: Key_293
429 key_code: 293
430 key_sym: "F12"
431 row: 1
432 col: 15
433
434 Key:
435 id: Key_178
436 key_code: 178
437 key_sym: "²"
438 row: 2
439 col: 1
440 Key:
441 id: Key_38
442 key_code: 38
443 key_sym: "&"
444 row: 2
445 col: 2
446 Key:
447 id: Key_233
448 key_code: 233
449 key_sym: "é"
450 row: 2
451 col: 3
452 Key:
453 id: Key_34
454 key_code: 34
455 key_sym: '"'
456 row: 2
457 col: 4
458 Key:
459 id: Key_39
460 key_code: 39
461 key_sym: "'"
462 row: 2
463 col: 5
464 Key:
465 id: Key_40
466 key_code: 40
467 key_sym: "("
468 row: 2
469 col: 6
470 Key:
471 id: Key_45
472 key_code: 45
473 key_sym: "-"
474 row: 2
475 col: 7
476 Key:
477 id: Key_232
478 key_code: 232
479 key_sym: "è"
480 row: 2
481 col: 8
482 Key:
483 id: Key_95
484 key_code: 95
485 key_sym: "_"
486 row: 2
487 col: 9
488 Key:
489 id: Key_231
490 key_code: 231
491 key_sym: "ç"
492 row: 2
493 col: 10
494 Key:
495 id: Key_224
496 key_code: 224
497 key_sym: "à"
498 row: 2
499 col: 11
500 Key:
501 id: Key_41
502 key_code: 41
503 key_sym: ")"
504 row: 2
505 col: 12
506 Key:
507 id: Key_61
508 key_code: 61
509 key_sym: "="
510 row: 2
511 col: 13
512 Key:
513 id: Key_8
514 key_code: 8
515 key_sym: "<-"
516 row: 2
517 col: 14
518 key_width: 2
519 Key:
520 id: Key_9
521 key_code: 9
522 key_sym: "tab"
523 row: 3
524 col: 1
525 key_width: 1.48
526 Key:
527 id: Key_97
528 key_code: 97
529 key_sym: "a"
530 row: 3
531 col: 2.5
532 Key:
533 id: Key_122
534 key_code: 122
535 key_sym: "z"
536 row: 3
537 col: 3.5
538 Key:
539 id: Key_101
540 key_code: 101
541 key_sym: "e"
542 row: 3
543 col: 4.5
544 Key:
545 id: Key_114
546 key_code: 114
547 key_sym: "r"
548 row: 3
549 col: 5.5
550 Key:
551 id: Key_116
552 key_code: 116
553 key_sym: "t"
554 row: 3
555 col: 6.5
556 Key:
557 id: Key_121
558 key_code: 121
559 key_sym: "y"
560 row: 3
561 col: 7.5
562 Key:
563 id: Key_117
564 key_code: 117
565 key_sym: "u"
566 row: 3
567 col: 8.5
568 Key:
569 id: Key_105
570 key_code: 105
571 key_sym: "i"
572 row: 3
573 col: 9.5
574 Key:
575 id: Key_111
576 key_code: 111
577 key_sym: "o"
578 row: 3
579 col: 10.5
580 Key:
581 id: Key_112
582 key_code: 112
583 key_sym: "p"
584 row: 3
585 col: 11.5
586 Key:
587 id: Key_94
588 key_code: 94
589 key_sym: "^"
590 row: 3
591 col: 12.5
592 Key:
593 id: Key_36
594 key_code: 36
595 key_sym: "$"
596 row: 3
597 col: 13.5
598 Key:
599 id: Key_13
600 key_code: 13
601 key_sym: "Enter"
602 row: 4
603 col: 14.8
604 key_width: 1.23
605 key_height: 2
606 Key:
607 id: Key_301
608 key_code: 301
609 key_sym: "CAPS"
610 row: 4
611 col: 1
612 key_width: 1.75
613 line_width: 1
614 enabled: False
615
616 Key:
617 id: Key_113
618 key_code: 113
619 key_sym: "q"
620 row: 4
621 col: 2.8
622 Key:
623 id: Key_115
624 key_code: 115
625 key_sym: "s"
626 row: 4
627 col: 3.8
628 Key:
629 id: Key_100
630 key_code: 100
631 key_sym: "d"
632 row: 4
633 col: 4.8
634 Key:
635 id: Key_102
636 key_code: 102
637 key_sym: "f"
638 row: 4
639 col: 5.8
640 Key:
641 id: Key_103
642 key_code: 103
643 key_sym: "g"
644 row: 4
645 col: 6.8
646 Key:
647 id: Key_104
648 key_code: 104
649 key_sym: "h"
650 row: 4
651 col: 7.8
652 Key:
653 id: Key_106
654 key_code: 106
655 key_sym: "j"
656 row: 4
657 col: 8.8
658 Key:
659 id: Key_107
660 key_code: 107
661 key_sym: "k"
662 row: 4
663 col: 9.8
664 Key:
665 id: Key_108
666 key_code: 108
667 key_sym: "l"
668 row: 4
669 col: 10.8
670 Key:
671 id: Key_109
672 key_code: 109
673 key_sym: "m"
674 row: 4
675 col: 11.8
676 Key:
677 id: Key_249
678 key_code: 249
679 key_sym: "ù"
680 row: 4
681 col: 12.8
682 Key:
683 id: Key_42
684 key_code: 42
685 key_sym: "*"
686 row: 4
687 col: 13.8
688 Key:
689 id: Key_304
690 key_code: 304
691 key_sym: "LShift"
692 row: 5
693 col: 1
694 key_width: 1.3
695 line_width: 1
696 enabled: False
697 Key:
698 id: Key_60
699 key_code: 60
700 key_sym: "<"
701 row: 5
702 col: 2.3
703 Key:
704 id: Key_119
705 key_code: 119
706 key_sym: "w"
707 row: 5
708 col: 3.3
709 Key:
710 id: Key_120
711 key_code: 120
712 key_sym: "x"
713 row: 5
714 col: 4.3
715 Key:
716 id: Key_99
717 key_code: 99
718 key_sym: "c"
719 row: 5
720 col: 5.3
721 Key:
722 id: Key_118
723 key_code: 118
724 key_sym: "v"
725 row: 5
726 col: 6.3
727 Key:
728 id: Key_98
729 key_code: 98
730 key_sym: "b"
731 row: 5
732 col: 7.3
733 Key:
734 id: Key_110
735 key_code: 110
736 key_sym: "n"
737 row: 5
738 col: 8.3
739 Key:
740 id: Key_44
741 key_code: 44
742 key_sym: ","
743 row: 5
744 col: 9.3
745 Key:
746 id: Key_59
747 key_code: 59
748 key_sym: ";"
749 row: 5
750 col: 10.3
751 Key:
752 id: Key_58
753 key_code: 58
754 key_sym: ":"
755 row: 5
756 col: 11.3
757 Key:
758 id: Key_33
759 key_code: 33
760 key_sym: "!"
761 row: 5
762 col: 12.3
763 Key:
764 id: Key_303
765 key_code: 303
766 key_sym: "RShift"
767 row: 5
768 col: 13.3
769 key_width: 2.7
770 line_width: 1
771 enabled: False
772 Key:
773 id: Key_306
774 key_code: 306
775 key_sym: "LCtrl"
776 row: 6
777 col: 1
778 key_width: 1.3
779 line_width: 1
780 enabled: False
781 Key:
782 id: Key_311
783 key_code: 311
784 key_sym: "LSuper"
785 row: 6
786 col: 3.3
787 line_width: 1
788 enabled: False
789 Key:
790 id: Key_308
791 key_code: 308
792 key_sym: "LAlt"
793 row: 6
794 col: 4.3
795 line_width: 1
796 enabled: False
797 Key:
798 id: Key_32
799 key_code: 32
800 key_sym: "Espace"
801 row: 6
802 col: 5.3
803 key_width: 5
804 Key:
805 id: Key_313
806 key_code: 313
807 key_sym: "AltGr"
808 row: 6
809 col: 10.3
810 line_width: 1
811 enabled: False
812 Key:
813 id: Key_314
814 key_code: 314
815 key_sym: "Compose"
816 row: 6
817 col: 11.3
818 line_width: 1
819 enabled: False
820 Key:
821 id: Key_305
822 key_code: 305
823 key_sym: "RCtrl"
824 row: 6
825 col: 12.3
826 key_width: 1.3
827 line_width: 1
828 enabled: False
829
830
831 Key:
832 id: Key_277
833 key_code: 277
834 key_sym: "ins"
835 row: 2
836 col: 1
837 pad_cols: True
838 Key:
839 id: Key_278
840 key_code: 278
841 key_sym: "home"
842 row: 2
843 col: 2
844 pad_cols: True
845 Key:
846 id: Key_280
847 key_code: 280
848 key_sym: "pg_u"
849 row: 2
850 col: 3
851 pad_cols: True
852 Key:
853 id: Key_127
854 key_code: 127
855 key_sym: "del"
856 row: 3
857 col: 1
858 pad_cols: True
859 Key:
860 id: Key_279
861 key_code: 279
862 key_sym: "end"
863 row: 3
864 col: 2
865 pad_cols: True
866 Key:
867 id: Key_281
868 key_code: 281
869 key_sym: "pg_d"
870 row: 3
871 col: 3
872 pad_cols: True
873 Key:
874 id: Key_273
875 key_code: 273
876 key_sym: "up"
877 row: 5
878 col: 2
879 pad_cols: True
880 Key:
881 id: Key_274
882 key_code: 274
883 key_sym: "down"
884 row: 6
885 col: 2
886 pad_cols: True
887 Key:
888 id: Key_276
889 key_code: 276
890 key_sym: "left"
891 row: 6
892 col: 1
893 pad_cols: True
894 Key:
895 id: Key_275
896 key_code: 275
897 key_sym: "right"
898 row: 6
899 col: 3
900 pad_cols: True