URL: https://linuxfr.org/users/gof/journaux/taptempo-en-slint Title: TapTempo en Slint Authors: Gof Date: 2024年11月06日T14:01:29+01:00 License: CC By-SA Tags: taptempo, slint et publicité Score: 26 Bonjour à tous, Ce journal s'inscrit dans la série des [journaux TapTempo](https://linuxfr.org/tags/taptempo/public). Je vous présente : **TapTempo en Slint** ! Pour ceux qui ne connaissent pas encore [Slint](https://slint.dev), c’est un toolkit pour créer des interfaces graphiques natives. Je suis l'un des développeurs, et j’en ai déjà parlé dans [ce journal](https://linuxfr.org/users/gof/journaux/slint-un-toolkit-pour-interface-graphiques-natives) et [cette dépêche](https://linuxfr.org/news/slint-1-0-une-boite-a-outils-graphiques-natifs-pour-poste-client-et-embarque). Dans ce portage de TapTempo, j'ai décidé de tout coder directement en Slint. Normalement, Slint sert principalement à construire l'interface utilisateur (UI), et la logique du programme est écrite dans le langage de programmation. Mais pour ce journal, j'ai intégré toute la logique directement en Slint. Pour réaliser cela, j'ai détourné la fonction `animation-tick()` pour mesurer le temps. Ce n’est pas la méthode la plus orthodoxe, je vous l'accorde, mais... ça fonctionne ! Voici le code : ```slint import { Slider, HorizontalBox } from "std-widgets.slint"; export component TapTempo inherits Window { property touch-count; property <[duration]> last_samples: [0ms, 0ms, 0ms, 0ms, 0ms, 0ms, 0ms, 0ms, 0ms, 0ms]; property sample-size: 5; property bpm; preferred-height: 200px; preferred-width: 600px; forward-focus: fs; VerticalLayout { padding: 0.5rem; text := Text { text: @tr("Hit enter key for each beat"); wrap: word-wrap; horizontal-alignment: left; vertical-alignment: center; font-size: 2rem; vertical-stretch: 1; } HorizontalBox { spacing: 1rem; Text { text: @tr("Sample size: {}", sample-size); vertical-alignment: center; } Slider { value: sample-size; minimum: 1; maximum: last_samples.length; changed(value) => { touch-count = 0; text.text = @tr("Hit enter key for each beat"); sample-size = value; fs.focus(); } } } } fs := FocusScope { key-pressed(e) => { if (e.text == "\n" || e.text == " ") { if (touch-count == 0) { text.text = @tr("Hit enter key one more time to start bpm computation..."); } else { if (touch-count < sample-size) { bpm = 60s / ((animation-tick() - last_samples[0]) / touch-count); } else { bpm = 60s / ((animation-tick() - last_samples[mod(touch-count, sample-size)]) / sample-size); } text.text = @tr("Tempo: {} bpm", bpm); } last_samples[mod(touch-count, sample-size)] = animation-tick(); touch-count += 1; return accept; } else if (e.text == "q") { touch-count = 0; bpm = 0; text.text = @tr("Bye Bye!"); return accept; } reject } } } ``` Et si vous voulez essayer, vous pouvez le faire directement en ligne grâce à **SlintPad**, notre éditeur/preview en ligne. [Lien vers SlintPad](https://slintpad.com/?snippet=import+%7B+Slider%2C+HorizontalBox+%7D+from+%22std-widgets.slint%22%3B%0Aexport+component+TapTempo+inherits+Window+%7B%0A++++property+%3Cint%3E+touch-count%3B%0A++++property+%3C%5Bduration%5D%3E+last_samples%3A+%5B0ms%2C+0ms%2C+0ms%2C+0ms%2C+0ms%2C+0ms%2C+0ms%2C+0ms%2C+0ms%2C+0ms%5D%3B%0A++++property+%3Cint%3E+sample-size%3A+5%3B%0A++++property+%3Cint%3E+bpm%3B%0A%0A++++preferred-height%3A+200px%3B%0A++++preferred-width%3A+600px%3B%0A++++forward-focus%3A+fs%3B%0A%0A++++VerticalLayout+%7B%0A++++++++padding%3A+0.5rem%3B%0A++++++++text+%3A%3D+Text+%7B%0A++++++++++++text%3A+%40tr%28%22Hit+enter+key+for+each+beat%22%29%3B%0A++++++++++++wrap%3A+word-wrap%3B%0A++++++++++++horizontal-alignment%3A+left%3B%0A++++++++++++vertical-alignment%3A+center%3B%0A++++++++++++font-size%3A+2rem%3B%0A++++++++++++vertical-stretch%3A+1%3B%0A++++++++%7D%0A%0A++++++++HorizontalBox+%7B%0A++++++++++++spacing%3A+1rem%3B%0A++++++++++++Text+%7B%0A++++++++++++++++text%3A+%40tr%28%22Sample+size%3A+%7B%7D%22%2C+sample-size%29%3B%0A++++++++++++++++vertical-alignment%3A+center%3B%0A++++++++++++%7D%0A%0A++++++++++++Slider+%7B%0A++++++++++++++++value%3A+sample-size%3B%0A++++++++++++++++minimum%3A+1%3B%0A++++++++++++++++maximum%3A+last_samples.length%3B%0A++++++++++++++++changed%28value%29+%3D%3E+%7B%0A++++++++++++++++++++touch-count+%3D+0%3B%0A++++++++++++++++++++text.text+%3D+%40tr%28%22Hit+enter+key+for+each+beat%22%29%3B%0A++++++++++++++++++++sample-size+%3D+value%3B%0A++++++++++++++++++++fs.focus%28%29%3B%0A++++++++++++++++%7D%0A++++++++++++%7D%0A++++++++%7D%0A++++%7D%0A%0A++++fs+%3A%3D+FocusScope+%7B%0A++++++++key-pressed%28e%29+%3D%3E+%7B%0A++++++++++++if+%28e.text+%3D%3D+%22%5Cn%22+%7C%7C+e.text+%3D%3D+%22+%22%29+%7B%0A++++++++++++++++if+%28touch-count+%3D%3D+0%29+%7B%0A++++++++++++++++++++text.text+%3D+%40tr%28%22Hit+enter+key+one+more+time+to+start+bpm+computation...%22%29%3B%0A++++++++++++++++%7D+else+%7B%0A++++++++++++++++++++if+%28touch-count+%3C+sample-size%29+%7B%0A++++++++++++++++++++++++bpm+%3D+60s+%2F+%28%28animation-tick%28%29+-+last_samples%5B0%5D%29+%2F+touch-count%29%3B%0A++++++++++++++++++++%7D+else+%7B%0A++++++++++++++++++++++++bpm+%3D+60s+%2F+%28%28animation-tick%28%29+-+last_samples%5Bmod%28touch-count%2C+sample-size%29%5D%29+%2F+sample-size%29%3B%0A++++++++++++++++++++%7D%0A++++++++++++++++++++text.text+%3D+%40tr%28%22Tempo%3A+%7B%7D+bpm%22%2C+bpm%29%3B%0A++++++++++++++++%7D%0A++++++++++++++++last_samples%5Bmod%28touch-count%2C+sample-size%29%5D+%3D+animation-tick%28%29%3B%0A++++++++++++++++touch-count+%2B%3D+1%3B%0A++++++++++++++++return+accept%3B%0A++++++++++++%7D+else+if+%28e.text+%3D%3D+%22q%22%29+%7B%0A++++++++++++++++touch-count+%3D+0%3B%0A++++++++++++++++bpm+%3D+0%3B%0A++++++++++++++++text.text+%3D+%40tr%28%22Bye+Bye%21%22%29%3B%0A++++++++++++++++return+accept%3B%0A++++++++++++%7D%0A++++++++++++reject%0A++++++++%7D%0A++++%7D%0A%7D%0A%0A%0A%0A)

AltStyle によって変換されたページ (->オリジナル) /