gradio-pianoroll 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. gradio_pianoroll-0.0.1/.gitignore +12 -0
  2. gradio_pianoroll-0.0.1/PKG-INFO +337 -0
  3. gradio_pianoroll-0.0.1/README.md +312 -0
  4. gradio_pianoroll-0.0.1/backend/gradio_pianoroll/__init__.py +4 -0
  5. gradio_pianoroll-0.0.1/backend/gradio_pianoroll/pianoroll.py +201 -0
  6. gradio_pianoroll-0.0.1/backend/gradio_pianoroll/pianoroll.pyi +292 -0
  7. gradio_pianoroll-0.0.1/backend/gradio_pianoroll/templates/component/index.js +20926 -0
  8. gradio_pianoroll-0.0.1/backend/gradio_pianoroll/templates/component/style.css +1 -0
  9. gradio_pianoroll-0.0.1/backend/gradio_pianoroll/templates/example/index.js +103 -0
  10. gradio_pianoroll-0.0.1/backend/gradio_pianoroll/templates/example/style.css +1 -0
  11. gradio_pianoroll-0.0.1/demo/__init__.py +0 -0
  12. gradio_pianoroll-0.0.1/demo/app.py +51 -0
  13. gradio_pianoroll-0.0.1/demo/css.css +157 -0
  14. gradio_pianoroll-0.0.1/demo/requirements.txt +1 -0
  15. gradio_pianoroll-0.0.1/demo/space.py +150 -0
  16. gradio_pianoroll-0.0.1/frontend/Example.svelte +19 -0
  17. gradio_pianoroll-0.0.1/frontend/Index.svelte +134 -0
  18. gradio_pianoroll-0.0.1/frontend/components/DebugComponent.svelte +179 -0
  19. gradio_pianoroll-0.0.1/frontend/components/GridComponent.svelte +1123 -0
  20. gradio_pianoroll-0.0.1/frontend/components/KeyboardComponent.svelte +228 -0
  21. gradio_pianoroll-0.0.1/frontend/components/PianoRoll.svelte +374 -0
  22. gradio_pianoroll-0.0.1/frontend/components/PlayheadComponent.svelte +82 -0
  23. gradio_pianoroll-0.0.1/frontend/components/TimeLineComponent.svelte +290 -0
  24. gradio_pianoroll-0.0.1/frontend/components/Toolbar.svelte +302 -0
  25. gradio_pianoroll-0.0.1/frontend/components/WaveformComponent.svelte +304 -0
  26. gradio_pianoroll-0.0.1/frontend/gradio.config.js +9 -0
  27. gradio_pianoroll-0.0.1/frontend/package-lock.json +6795 -0
  28. gradio_pianoroll-0.0.1/frontend/package.json +43 -0
  29. gradio_pianoroll-0.0.1/frontend/tsconfig.json +17 -0
  30. gradio_pianoroll-0.0.1/frontend/utils/audioEngine.ts +294 -0
  31. gradio_pianoroll-0.0.1/frontend/utils/flicks.ts +76 -0
  32. gradio_pianoroll-0.0.1/pyproject.toml +51 -0
@@ -0,0 +1,12 @@
1
+ .eggs/
2
+ dist/
3
+ *.pyc
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+ __tmp/*
8
+ *.pyi
9
+ .mypycache
10
+ .ruff_cache
11
+ node_modules
12
+ backend/**/templates/
@@ -0,0 +1,337 @@
1
+ Metadata-Version: 2.4
2
+ Name: gradio_pianoroll
3
+ Version: 0.0.1
4
+ Summary: A PianoRoll Component for Gradio.
5
+ Author-email: YOUR NAME <YOUREMAIL@domain.com>
6
+ License-Expression: Apache-2.0
7
+ Keywords: gradio-custom-component,gradio-template-Fallback
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Classifier: Topic :: Scientific/Engineering :: Visualization
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: gradio<6.0,>=4.0
21
+ Provides-Extra: dev
22
+ Requires-Dist: build; extra == 'dev'
23
+ Requires-Dist: twine; extra == 'dev'
24
+ Description-Content-Type: text/markdown
25
+
26
+ ---
27
+ tags: [gradio-custom-component, ]
28
+ title: gradio_pianoroll
29
+ short_description: A PianoRoll Component for
30
+ colorFrom: blue
31
+ colorTo: yellow
32
+ sdk: gradio
33
+ pinned: false
34
+ app_file: space.py
35
+ ---
36
+
37
+ # `gradio_pianoroll`
38
+ <img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.1%20-%20orange">
39
+
40
+ A PianoRoll Component for Gradio.
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install gradio_pianoroll
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ ```python
51
+ import gradio as gr
52
+ from gradio_pianoroll import PianoRoll
53
+
54
+ def convert(piano_roll):
55
+ print("=== Convert function called ===")
56
+ print("Received piano_roll:")
57
+ print(piano_roll)
58
+ print("Type:", type(piano_roll))
59
+ return piano_roll
60
+ with gr.Blocks() as demo:
61
+ gr.Markdown("# Gradio PianoRoll: Gradio에서 피아노롤 컴포넌트 사용")
62
+
63
+ with gr.Row():
64
+ with gr.Column():
65
+ # 초기값을 명시적으로 설정
66
+ initial_value = {
67
+ "notes": [
68
+ {
69
+ "id": "note-1",
70
+ "start": 80,
71
+ "duration": 80,
72
+ "pitch": 60,
73
+ "velocity": 100,
74
+ "lyric": "테스트"
75
+ }
76
+ ],
77
+ "tempo": 140,
78
+ "timeSignature": {"numerator": 4, "denominator": 4},
79
+ "editMode": "select",
80
+ "snapSetting": "1/4"
81
+ }
82
+ piano_roll = PianoRoll(height=600, width=1000, value=initial_value)
83
+
84
+ with gr.Row():
85
+ with gr.Column():
86
+ output_json = gr.JSON()
87
+
88
+ with gr.Row():
89
+ with gr.Column():
90
+ btn = gr.Button("Convert & Debug")
91
+
92
+ # 버튼 클릭 이벤트
93
+ btn.click(
94
+ fn=convert,
95
+ inputs=piano_roll,
96
+ outputs=output_json,
97
+ show_progress=True
98
+ )
99
+
100
+ if __name__ == "__main__":
101
+ demo.launch()
102
+
103
+ ```
104
+
105
+ ## `PianoRoll`
106
+
107
+ ### Initialization
108
+
109
+ <table>
110
+ <thead>
111
+ <tr>
112
+ <th align="left">name</th>
113
+ <th align="left" style="width: 25%;">type</th>
114
+ <th align="left">default</th>
115
+ <th align="left">description</th>
116
+ </tr>
117
+ </thead>
118
+ <tbody>
119
+ <tr>
120
+ <td align="left"><code>value</code></td>
121
+ <td align="left" style="width: 25%;">
122
+
123
+ ```python
124
+ dict | None
125
+ ```
126
+
127
+ </td>
128
+ <td align="left"><code>None</code></td>
129
+ <td align="left">default MIDI notes data to provide in piano roll. If a function is provided, the function will be called each time the app loads to set the initial value of this component.</td>
130
+ </tr>
131
+
132
+ <tr>
133
+ <td align="left"><code>label</code></td>
134
+ <td align="left" style="width: 25%;">
135
+
136
+ ```python
137
+ str | I18nData | None
138
+ ```
139
+
140
+ </td>
141
+ <td align="left"><code>None</code></td>
142
+ <td align="left">the label for this component, displayed above the component if `show_label` is `True` and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component corresponds to.</td>
143
+ </tr>
144
+
145
+ <tr>
146
+ <td align="left"><code>every</code></td>
147
+ <td align="left" style="width: 25%;">
148
+
149
+ ```python
150
+ "Timer | float | None"
151
+ ```
152
+
153
+ </td>
154
+ <td align="left"><code>None</code></td>
155
+ <td align="left">Continously calls `value` to recalculate it if `value` is a function (has no effect otherwise). Can provide a Timer whose tick resets `value`, or a float that provides the regular interval for the reset Timer.</td>
156
+ </tr>
157
+
158
+ <tr>
159
+ <td align="left"><code>inputs</code></td>
160
+ <td align="left" style="width: 25%;">
161
+
162
+ ```python
163
+ Component | Sequence[Component] | set[Component] | None
164
+ ```
165
+
166
+ </td>
167
+ <td align="left"><code>None</code></td>
168
+ <td align="left">Components that are used as inputs to calculate `value` if `value` is a function (has no effect otherwise). `value` is recalculated any time the inputs change.</td>
169
+ </tr>
170
+
171
+ <tr>
172
+ <td align="left"><code>show_label</code></td>
173
+ <td align="left" style="width: 25%;">
174
+
175
+ ```python
176
+ bool | None
177
+ ```
178
+
179
+ </td>
180
+ <td align="left"><code>None</code></td>
181
+ <td align="left">if True, will display label.</td>
182
+ </tr>
183
+
184
+ <tr>
185
+ <td align="left"><code>scale</code></td>
186
+ <td align="left" style="width: 25%;">
187
+
188
+ ```python
189
+ int | None
190
+ ```
191
+
192
+ </td>
193
+ <td align="left"><code>None</code></td>
194
+ <td align="left">relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.</td>
195
+ </tr>
196
+
197
+ <tr>
198
+ <td align="left"><code>min_width</code></td>
199
+ <td align="left" style="width: 25%;">
200
+
201
+ ```python
202
+ int
203
+ ```
204
+
205
+ </td>
206
+ <td align="left"><code>160</code></td>
207
+ <td align="left">minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.</td>
208
+ </tr>
209
+
210
+ <tr>
211
+ <td align="left"><code>interactive</code></td>
212
+ <td align="left" style="width: 25%;">
213
+
214
+ ```python
215
+ bool | None
216
+ ```
217
+
218
+ </td>
219
+ <td align="left"><code>None</code></td>
220
+ <td align="left">if True, will be rendered as an editable piano roll; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.</td>
221
+ </tr>
222
+
223
+ <tr>
224
+ <td align="left"><code>visible</code></td>
225
+ <td align="left" style="width: 25%;">
226
+
227
+ ```python
228
+ bool
229
+ ```
230
+
231
+ </td>
232
+ <td align="left"><code>True</code></td>
233
+ <td align="left">If False, component will be hidden.</td>
234
+ </tr>
235
+
236
+ <tr>
237
+ <td align="left"><code>elem_id</code></td>
238
+ <td align="left" style="width: 25%;">
239
+
240
+ ```python
241
+ str | None
242
+ ```
243
+
244
+ </td>
245
+ <td align="left"><code>None</code></td>
246
+ <td align="left">An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.</td>
247
+ </tr>
248
+
249
+ <tr>
250
+ <td align="left"><code>elem_classes</code></td>
251
+ <td align="left" style="width: 25%;">
252
+
253
+ ```python
254
+ list[str] | str | None
255
+ ```
256
+
257
+ </td>
258
+ <td align="left"><code>None</code></td>
259
+ <td align="left">An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.</td>
260
+ </tr>
261
+
262
+ <tr>
263
+ <td align="left"><code>render</code></td>
264
+ <td align="left" style="width: 25%;">
265
+
266
+ ```python
267
+ bool
268
+ ```
269
+
270
+ </td>
271
+ <td align="left"><code>True</code></td>
272
+ <td align="left">If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.</td>
273
+ </tr>
274
+
275
+ <tr>
276
+ <td align="left"><code>key</code></td>
277
+ <td align="left" style="width: 25%;">
278
+
279
+ ```python
280
+ int | str | tuple[int | str, ...] | None
281
+ ```
282
+
283
+ </td>
284
+ <td align="left"><code>None</code></td>
285
+ <td align="left">in a gr.render, Components with the same key across re-renders are treated as the same component, not a new component. Properties set in 'preserved_by_key' are not reset across a re-render.</td>
286
+ </tr>
287
+
288
+ <tr>
289
+ <td align="left"><code>preserved_by_key</code></td>
290
+ <td align="left" style="width: 25%;">
291
+
292
+ ```python
293
+ list[str] | str | None
294
+ ```
295
+
296
+ </td>
297
+ <td align="left"><code>"value"</code></td>
298
+ <td align="left">A list of parameters from this component's constructor. Inside a gr.render() function, if a component is re-rendered with the same key, these (and only these) parameters will be preserved in the UI (if they have been changed by the user or an event listener) instead of re-rendered based on the values provided during constructor.</td>
299
+ </tr>
300
+
301
+ <tr>
302
+ <td align="left"><code>width</code></td>
303
+ <td align="left" style="width: 25%;">
304
+
305
+ ```python
306
+ int | None
307
+ ```
308
+
309
+ </td>
310
+ <td align="left"><code>1000</code></td>
311
+ <td align="left">width of the piano roll component in pixels.</td>
312
+ </tr>
313
+
314
+ <tr>
315
+ <td align="left"><code>height</code></td>
316
+ <td align="left" style="width: 25%;">
317
+
318
+ ```python
319
+ int | None
320
+ ```
321
+
322
+ </td>
323
+ <td align="left"><code>600</code></td>
324
+ <td align="left">height of the piano roll component in pixels.</td>
325
+ </tr>
326
+ </tbody></table>
327
+
328
+
329
+ ### Events
330
+
331
+ | name | description |
332
+ |:-----|:------------|
333
+ | `change` | Triggered when the value of the PianoRoll changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See `.input()` for a listener that is only triggered by user input. |
334
+ | `input` | This listener is triggered when the user changes the value of the PianoRoll. |
335
+
336
+
337
+
@@ -0,0 +1,312 @@
1
+ ---
2
+ tags: [gradio-custom-component, ]
3
+ title: gradio_pianoroll
4
+ short_description: A PianoRoll Component for
5
+ colorFrom: blue
6
+ colorTo: yellow
7
+ sdk: gradio
8
+ pinned: false
9
+ app_file: space.py
10
+ ---
11
+
12
+ # `gradio_pianoroll`
13
+ <img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.1%20-%20orange">
14
+
15
+ A PianoRoll Component for Gradio.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install gradio_pianoroll
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```python
26
+ import gradio as gr
27
+ from gradio_pianoroll import PianoRoll
28
+
29
+ def convert(piano_roll):
30
+ print("=== Convert function called ===")
31
+ print("Received piano_roll:")
32
+ print(piano_roll)
33
+ print("Type:", type(piano_roll))
34
+ return piano_roll
35
+ with gr.Blocks() as demo:
36
+ gr.Markdown("# Gradio PianoRoll: Gradio에서 피아노롤 컴포넌트 사용")
37
+
38
+ with gr.Row():
39
+ with gr.Column():
40
+ # 초기값을 명시적으로 설정
41
+ initial_value = {
42
+ "notes": [
43
+ {
44
+ "id": "note-1",
45
+ "start": 80,
46
+ "duration": 80,
47
+ "pitch": 60,
48
+ "velocity": 100,
49
+ "lyric": "테스트"
50
+ }
51
+ ],
52
+ "tempo": 140,
53
+ "timeSignature": {"numerator": 4, "denominator": 4},
54
+ "editMode": "select",
55
+ "snapSetting": "1/4"
56
+ }
57
+ piano_roll = PianoRoll(height=600, width=1000, value=initial_value)
58
+
59
+ with gr.Row():
60
+ with gr.Column():
61
+ output_json = gr.JSON()
62
+
63
+ with gr.Row():
64
+ with gr.Column():
65
+ btn = gr.Button("Convert & Debug")
66
+
67
+ # 버튼 클릭 이벤트
68
+ btn.click(
69
+ fn=convert,
70
+ inputs=piano_roll,
71
+ outputs=output_json,
72
+ show_progress=True
73
+ )
74
+
75
+ if __name__ == "__main__":
76
+ demo.launch()
77
+
78
+ ```
79
+
80
+ ## `PianoRoll`
81
+
82
+ ### Initialization
83
+
84
+ <table>
85
+ <thead>
86
+ <tr>
87
+ <th align="left">name</th>
88
+ <th align="left" style="width: 25%;">type</th>
89
+ <th align="left">default</th>
90
+ <th align="left">description</th>
91
+ </tr>
92
+ </thead>
93
+ <tbody>
94
+ <tr>
95
+ <td align="left"><code>value</code></td>
96
+ <td align="left" style="width: 25%;">
97
+
98
+ ```python
99
+ dict | None
100
+ ```
101
+
102
+ </td>
103
+ <td align="left"><code>None</code></td>
104
+ <td align="left">default MIDI notes data to provide in piano roll. If a function is provided, the function will be called each time the app loads to set the initial value of this component.</td>
105
+ </tr>
106
+
107
+ <tr>
108
+ <td align="left"><code>label</code></td>
109
+ <td align="left" style="width: 25%;">
110
+
111
+ ```python
112
+ str | I18nData | None
113
+ ```
114
+
115
+ </td>
116
+ <td align="left"><code>None</code></td>
117
+ <td align="left">the label for this component, displayed above the component if `show_label` is `True` and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component corresponds to.</td>
118
+ </tr>
119
+
120
+ <tr>
121
+ <td align="left"><code>every</code></td>
122
+ <td align="left" style="width: 25%;">
123
+
124
+ ```python
125
+ "Timer | float | None"
126
+ ```
127
+
128
+ </td>
129
+ <td align="left"><code>None</code></td>
130
+ <td align="left">Continously calls `value` to recalculate it if `value` is a function (has no effect otherwise). Can provide a Timer whose tick resets `value`, or a float that provides the regular interval for the reset Timer.</td>
131
+ </tr>
132
+
133
+ <tr>
134
+ <td align="left"><code>inputs</code></td>
135
+ <td align="left" style="width: 25%;">
136
+
137
+ ```python
138
+ Component | Sequence[Component] | set[Component] | None
139
+ ```
140
+
141
+ </td>
142
+ <td align="left"><code>None</code></td>
143
+ <td align="left">Components that are used as inputs to calculate `value` if `value` is a function (has no effect otherwise). `value` is recalculated any time the inputs change.</td>
144
+ </tr>
145
+
146
+ <tr>
147
+ <td align="left"><code>show_label</code></td>
148
+ <td align="left" style="width: 25%;">
149
+
150
+ ```python
151
+ bool | None
152
+ ```
153
+
154
+ </td>
155
+ <td align="left"><code>None</code></td>
156
+ <td align="left">if True, will display label.</td>
157
+ </tr>
158
+
159
+ <tr>
160
+ <td align="left"><code>scale</code></td>
161
+ <td align="left" style="width: 25%;">
162
+
163
+ ```python
164
+ int | None
165
+ ```
166
+
167
+ </td>
168
+ <td align="left"><code>None</code></td>
169
+ <td align="left">relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.</td>
170
+ </tr>
171
+
172
+ <tr>
173
+ <td align="left"><code>min_width</code></td>
174
+ <td align="left" style="width: 25%;">
175
+
176
+ ```python
177
+ int
178
+ ```
179
+
180
+ </td>
181
+ <td align="left"><code>160</code></td>
182
+ <td align="left">minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.</td>
183
+ </tr>
184
+
185
+ <tr>
186
+ <td align="left"><code>interactive</code></td>
187
+ <td align="left" style="width: 25%;">
188
+
189
+ ```python
190
+ bool | None
191
+ ```
192
+
193
+ </td>
194
+ <td align="left"><code>None</code></td>
195
+ <td align="left">if True, will be rendered as an editable piano roll; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.</td>
196
+ </tr>
197
+
198
+ <tr>
199
+ <td align="left"><code>visible</code></td>
200
+ <td align="left" style="width: 25%;">
201
+
202
+ ```python
203
+ bool
204
+ ```
205
+
206
+ </td>
207
+ <td align="left"><code>True</code></td>
208
+ <td align="left">If False, component will be hidden.</td>
209
+ </tr>
210
+
211
+ <tr>
212
+ <td align="left"><code>elem_id</code></td>
213
+ <td align="left" style="width: 25%;">
214
+
215
+ ```python
216
+ str | None
217
+ ```
218
+
219
+ </td>
220
+ <td align="left"><code>None</code></td>
221
+ <td align="left">An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.</td>
222
+ </tr>
223
+
224
+ <tr>
225
+ <td align="left"><code>elem_classes</code></td>
226
+ <td align="left" style="width: 25%;">
227
+
228
+ ```python
229
+ list[str] | str | None
230
+ ```
231
+
232
+ </td>
233
+ <td align="left"><code>None</code></td>
234
+ <td align="left">An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.</td>
235
+ </tr>
236
+
237
+ <tr>
238
+ <td align="left"><code>render</code></td>
239
+ <td align="left" style="width: 25%;">
240
+
241
+ ```python
242
+ bool
243
+ ```
244
+
245
+ </td>
246
+ <td align="left"><code>True</code></td>
247
+ <td align="left">If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.</td>
248
+ </tr>
249
+
250
+ <tr>
251
+ <td align="left"><code>key</code></td>
252
+ <td align="left" style="width: 25%;">
253
+
254
+ ```python
255
+ int | str | tuple[int | str, ...] | None
256
+ ```
257
+
258
+ </td>
259
+ <td align="left"><code>None</code></td>
260
+ <td align="left">in a gr.render, Components with the same key across re-renders are treated as the same component, not a new component. Properties set in 'preserved_by_key' are not reset across a re-render.</td>
261
+ </tr>
262
+
263
+ <tr>
264
+ <td align="left"><code>preserved_by_key</code></td>
265
+ <td align="left" style="width: 25%;">
266
+
267
+ ```python
268
+ list[str] | str | None
269
+ ```
270
+
271
+ </td>
272
+ <td align="left"><code>"value"</code></td>
273
+ <td align="left">A list of parameters from this component's constructor. Inside a gr.render() function, if a component is re-rendered with the same key, these (and only these) parameters will be preserved in the UI (if they have been changed by the user or an event listener) instead of re-rendered based on the values provided during constructor.</td>
274
+ </tr>
275
+
276
+ <tr>
277
+ <td align="left"><code>width</code></td>
278
+ <td align="left" style="width: 25%;">
279
+
280
+ ```python
281
+ int | None
282
+ ```
283
+
284
+ </td>
285
+ <td align="left"><code>1000</code></td>
286
+ <td align="left">width of the piano roll component in pixels.</td>
287
+ </tr>
288
+
289
+ <tr>
290
+ <td align="left"><code>height</code></td>
291
+ <td align="left" style="width: 25%;">
292
+
293
+ ```python
294
+ int | None
295
+ ```
296
+
297
+ </td>
298
+ <td align="left"><code>600</code></td>
299
+ <td align="left">height of the piano roll component in pixels.</td>
300
+ </tr>
301
+ </tbody></table>
302
+
303
+
304
+ ### Events
305
+
306
+ | name | description |
307
+ |:-----|:------------|
308
+ | `change` | Triggered when the value of the PianoRoll changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See `.input()` for a listener that is only triggered by user input. |
309
+ | `input` | This listener is triggered when the user changes the value of the PianoRoll. |
310
+
311
+
312
+
@@ -0,0 +1,4 @@
1
+
2
+ from .pianoroll import PianoRoll
3
+
4
+ __all__ = ['PianoRoll']