diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-07-28 17:26:26 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-07-28 17:27:48 +0200 |
commit | d734981b5145f1798f3301c135dc577b7aef293e (patch) | |
tree | 50dc1bc8d00d3f853bff71a03be05111d7a44b7b | |
parent | d7d6f2bebfc9eb4f3f8233eb70577e4c2ff31bd3 (diff) | |
download | MusicSampler-d734981b5145f1798f3301c135dc577b7aef293e.tar.gz MusicSampler-d734981b5145f1798f3301c135dc577b7aef293e.tar.zst MusicSampler-d734981b5145f1798f3301c135dc577b7aef293e.zip |
Use labels stacking to build playlist
-rw-r--r-- | music_sampler/app.py | 33 | ||||
-rw-r--r-- | music_sampler/app_blocks/__init__.py | 1 | ||||
-rw-r--r-- | music_sampler/app_blocks/playlist.py | 125 | ||||
-rw-r--r-- | music_sampler/music_sampler.kv | 92 |
4 files changed, 176 insertions, 75 deletions
diff --git a/music_sampler/app.py b/music_sampler/app.py index 81c47a7..510cb44 100644 --- a/music_sampler/app.py +++ b/music_sampler/app.py | |||
@@ -1,4 +1,4 @@ | |||
1 | from .helpers import parse_args, register_fonts, duration_to_min_sec, path | 1 | from .helpers import parse_args, register_fonts, path |
2 | 2 | ||
3 | parse_args() | 3 | parse_args() |
4 | 4 | ||
@@ -6,9 +6,9 @@ import kivy | |||
6 | kivy.require("1.9.1") | 6 | kivy.require("1.9.1") |
7 | from kivy.app import App | 7 | from kivy.app import App |
8 | from kivy.uix.floatlayout import FloatLayout | 8 | from kivy.uix.floatlayout import FloatLayout |
9 | from kivy.uix.stacklayout import StackLayout | ||
9 | from kivy.uix.relativelayout import RelativeLayout | 10 | from kivy.uix.relativelayout import RelativeLayout |
10 | from kivy.properties import ListProperty, StringProperty | 11 | from kivy.properties import ListProperty, StringProperty |
11 | from kivy.clock import Clock | ||
12 | from kivy.core.window import Window | 12 | from kivy.core.window import Window |
13 | from kivy.lang import Builder | 13 | from kivy.lang import Builder |
14 | from .key import Key | 14 | from .key import Key |
@@ -16,6 +16,8 @@ from .mapping import Mapping | |||
16 | 16 | ||
17 | register_fonts() | 17 | register_fonts() |
18 | 18 | ||
19 | from .app_blocks.playlist import * | ||
20 | |||
19 | class KeyList(RelativeLayout): | 21 | class KeyList(RelativeLayout): |
20 | keylist = ListProperty([]) | 22 | keylist = ListProperty([]) |
21 | first_key = StringProperty("") | 23 | first_key = StringProperty("") |
@@ -33,33 +35,6 @@ class KeyList(RelativeLayout): | |||
33 | if len(self.keylist) > 2: | 35 | if len(self.keylist) > 2: |
34 | self.third_key = self.keylist[2] | 36 | self.third_key = self.keylist[2] |
35 | 37 | ||
36 | class 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 | |||
63 | class ActionList(RelativeLayout): | 38 | class ActionList(RelativeLayout): |
64 | action_title = StringProperty("") | 39 | action_title = StringProperty("") |
65 | action_list = ListProperty([]) | 40 | action_list = ListProperty([]) |
diff --git a/music_sampler/app_blocks/__init__.py b/music_sampler/app_blocks/__init__.py new file mode 100644 index 0000000..c412eb1 --- /dev/null +++ b/music_sampler/app_blocks/__init__.py | |||
@@ -0,0 +1 @@ | |||
from . import playlist | |||
diff --git a/music_sampler/app_blocks/playlist.py b/music_sampler/app_blocks/playlist.py new file mode 100644 index 0000000..b704d4d --- /dev/null +++ b/music_sampler/app_blocks/playlist.py | |||
@@ -0,0 +1,125 @@ | |||
1 | from kivy.uix.label import Label | ||
2 | from kivy.uix.stacklayout import StackLayout | ||
3 | from kivy.uix.relativelayout import RelativeLayout | ||
4 | from kivy.properties import ListProperty | ||
5 | from kivy.clock import Clock | ||
6 | from ..helpers import duration_to_min_sec | ||
7 | |||
8 | import math | ||
9 | |||
10 | __all__ = ["PlayList", | ||
11 | "PlayListIcons", "PlayListIcon", | ||
12 | "PlayListNames", "PlayListName", | ||
13 | "PlayListTimes", "PlayListTime"] | ||
14 | |||
15 | class PlayList(RelativeLayout): | ||
16 | playlist = ListProperty([]) | ||
17 | |||
18 | def __init__(self, **kwargs): | ||
19 | super(PlayList, self).__init__(**kwargs) | ||
20 | Clock.schedule_interval(self.update_playlist, 0.5) | ||
21 | |||
22 | def update_playlist(self, dt): | ||
23 | if self.parent is None or 'Mapping' not in self.parent.ids: | ||
24 | return True | ||
25 | |||
26 | open_files = self.parent.ids['Mapping'].open_files | ||
27 | playlist = [] | ||
28 | for music_file in open_files.values(): | ||
29 | if not music_file.is_in_use(): | ||
30 | continue | ||
31 | |||
32 | time_info = "{}/{}".format( | ||
33 | duration_to_min_sec(music_file.sound_position), | ||
34 | duration_to_min_sec(music_file.sound_duration)) | ||
35 | |||
36 | if music_file.is_loaded_paused(): | ||
37 | playlist.append(["⏸", music_file.name, time_info, False]) | ||
38 | else: | ||
39 | playlist.append(["⏵", music_file.name, time_info, True]) | ||
40 | self.playlist = playlist | ||
41 | |||
42 | |||
43 | class PlayListIcons(StackLayout): | ||
44 | def __init__(self, **kwargs): | ||
45 | super(PlayListIcons, self).__init__(**kwargs) | ||
46 | self.icons = [] | ||
47 | |||
48 | def on_parent(self, instance, parent): | ||
49 | parent.bind(playlist=self.update_playlist_icons) | ||
50 | |||
51 | def update_playlist_icons(self, instance, playlist): | ||
52 | for icon in self.icons: | ||
53 | self.remove_widget(icon) | ||
54 | self.icons = [] | ||
55 | for icon, filename, time_info, playing in playlist: | ||
56 | icon_label = PlayListIcon(text=icon) | ||
57 | self.add_widget(icon_label) | ||
58 | self.icons.append(icon_label) | ||
59 | |||
60 | class PlayListIcon(Label): | ||
61 | def __init__(self, text='', **kwargs): | ||
62 | super(PlayListIcon, self).__init__(**kwargs) | ||
63 | self.text = text | ||
64 | |||
65 | def on_parent(self, instance, parent): | ||
66 | if parent is not None: | ||
67 | self.font_size = math.ceil(2 * math.sqrt(parent.parent.parent.key_size)) | ||
68 | self.height = parent.parent.labels_height | ||
69 | |||
70 | |||
71 | class PlayListNames(StackLayout): | ||
72 | def __init__(self, **kwargs): | ||
73 | super(PlayListNames, self).__init__(**kwargs) | ||
74 | self.names = [] | ||
75 | |||
76 | def on_parent(self, instance, parent): | ||
77 | parent.bind(playlist=self.update_playlist_names) | ||
78 | |||
79 | def update_playlist_names(self, instance, playlist): | ||
80 | for name in self.names: | ||
81 | self.remove_widget(name) | ||
82 | self.names = [] | ||
83 | for icon, filename, time_info, playing in playlist: | ||
84 | name_label = PlayListName(text=filename, is_playing=playing) | ||
85 | self.add_widget(name_label) | ||
86 | self.names.append(name_label) | ||
87 | |||
88 | class PlayListName(Label): | ||
89 | def __init__(self, text='', is_playing=False, **kwargs): | ||
90 | super(PlayListName, self).__init__(**kwargs) | ||
91 | self.text = text | ||
92 | self.bold = is_playing | ||
93 | |||
94 | def on_parent(self, instance, parent): | ||
95 | if parent is not None: | ||
96 | self.font_size = math.ceil(2 * math.sqrt(parent.parent.parent.key_size)) | ||
97 | self.height = parent.parent.labels_height | ||
98 | |||
99 | class PlayListTimes(StackLayout): | ||
100 | def __init__(self, **kwargs): | ||
101 | super(PlayListTimes, self).__init__(**kwargs) | ||
102 | self.times = [] | ||
103 | |||
104 | def on_parent(self, instance, parent): | ||
105 | parent.bind(playlist=self.update_playlist_times) | ||
106 | |||
107 | def update_playlist_times(self, instance, playlist): | ||
108 | for time in self.times: | ||
109 | self.remove_widget(time) | ||
110 | self.times = [] | ||
111 | for icon, filename, time_info, playing in playlist: | ||
112 | time_label = PlayListTime(text=time_info) | ||
113 | self.add_widget(time_label) | ||
114 | self.times.append(time_label) | ||
115 | |||
116 | class PlayListTime(Label): | ||
117 | def __init__(self, text='', **kwargs): | ||
118 | super(PlayListTime, self).__init__(**kwargs) | ||
119 | self.text = text | ||
120 | |||
121 | def on_parent(self, instance, parent): | ||
122 | if parent is not None: | ||
123 | self.font_size = math.ceil(2 * math.sqrt(parent.parent.parent.key_size)) | ||
124 | self.height = parent.parent.labels_height | ||
125 | |||
diff --git a/music_sampler/music_sampler.kv b/music_sampler/music_sampler.kv index 9057532..8e94da8 100644 --- a/music_sampler/music_sampler.kv +++ b/music_sampler/music_sampler.kv | |||
@@ -105,14 +105,16 @@ | |||
105 | action_list_y: self.border | 105 | action_list_y: self.border |
106 | 106 | ||
107 | play_list_height: self.action_list_height | 107 | play_list_height: self.action_list_height |
108 | play_list_width: self.width - self.action_list_width - 3* self.border | 108 | play_list_width: self.width - self.key_list_width - self.action_list_width - 4* self.border |
109 | play_list_y: self.border | 109 | play_list_y: self.border |
110 | play_list_x: self.action_list_width + self.key_list_width + 3 * self.border | 110 | play_list_x: self.action_list_width + self.key_list_width + 3 * self.border |
111 | 111 | ||
112 | max_height: max(mock_symbola.height, mock_ubuntu_regular.height, mock_ubuntu_bold.height) | ||
112 | min_height: min(mock_symbola.height, mock_ubuntu_regular.height, mock_ubuntu_bold.height) | 113 | 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 | 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_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 | ubuntu_bold_line_height: self.min_height / max(mock_ubuntu_bold.height,1) |
117 | |||
116 | Label: | 118 | Label: |
117 | id: mock_symbola | 119 | id: mock_symbola |
118 | font_name: "Symbola" | 120 | font_name: "Symbola" |
@@ -271,58 +273,56 @@ | |||
271 | 273 | ||
272 | <PlayList>: | 274 | <PlayList>: |
273 | size_hint: None, None | 275 | size_hint: None, None |
276 | labels_height: self.parent.max_height or 1 | ||
274 | canvas: | 277 | canvas: |
275 | Color: | 278 | Color: |
276 | rgba: 250./255, 250./255, 250./255, 1 | 279 | rgba: 250./255, 250./255, 250./255, 1 |
277 | Rectangle: | 280 | Rectangle: |
278 | pos: 0, 0 | 281 | pos: 0, 0 |
279 | size: self.width, self.height | 282 | size: self.width, self.height |
280 | 283 | PlayListIcons: | |
281 | Label: | 284 | orientation: 'lr-tb' |
282 | id: playlist_icons | 285 | size_hint: 0.05, 1 |
283 | font_name: "Symbola" | 286 | pos_hints: { 'x': 0, 'top': 0 } |
284 | font_size: math.ceil(2 * math.sqrt(self.parent.parent.key_size or 10)) | 287 | PlayListNames: |
285 | line_height: self.parent.parent.symbola_line_height or 1 | 288 | orientation: 'lr-tb' |
286 | color: 0, 0, 0, 1 | 289 | pos_hint: { 'x': 0.05, 'bottom': 0 } |
287 | text: "\n".join(map(lambda x: x[0], self.parent.playlist)) | 290 | size_hint: 0.65, 1 |
288 | text_size: None, self.parent.height | 291 | PlayListTimes: |
289 | halign: "left" | 292 | orientation: 'lr-tb' |
290 | valign: "top" | 293 | pos_hint: { 'x': 0.7, 'bottom': 0 } |
291 | size_hint: None, None | 294 | size_hint: 0.30, 1 |
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 | 295 | ||
296 | <PlayListIcon>: | ||
297 | font_name: "Symbola" | ||
298 | color: 0, 0, 0, 1 | ||
299 | text_size: None, None | ||
300 | halign: "left" | ||
301 | size_hint: 1, None | ||
302 | width: self.texture_size[0] | ||
303 | |||
304 | <PlayListName>: | ||
305 | font_name: "Ubuntu" | ||
306 | color: 0, 0, 0, 1 | ||
307 | text_size: None, None | ||
308 | halign: "left" | ||
309 | size_hint: None, None | ||
310 | width: self.texture_size[0] | ||
311 | |||
312 | <PlayListTime>: | ||
313 | canvas.before: | ||
314 | Color: | ||
315 | rgba: 250./255, 250./255, 250./255, 1 | ||
316 | Rectangle: | ||
317 | pos: self.pos | ||
318 | size: self.width, self.height | ||
319 | font_name: "Ubuntu" | ||
320 | color: 0, 0, 0, 1 | ||
321 | text_size: None, None | ||
322 | halign: "left" | ||
323 | size_hint: None, None | ||
324 | width: self.texture_size[0] | ||
325 | |||
326 | <Mapping>: | 326 | <Mapping>: |
327 | size_hint: None, None | 327 | size_hint: None, None |
328 | key_size: 48 | 328 | key_size: 48 |