[addressed] Norns UI and Pages

Anyone know of any good examples of using the Norns Lua UI widgets.

I’ve been trying to come up with the paging system from scratch, and it’s not going terribly well, so I thought I’d have a go with the builtin widgets, to see it that simplifies things at all.

I’m a bit confused as to how to add items to a page, currently, and also how to shift focus from one one control to another, on a given page.

I found the UI demo script to be the most helpful.

It sounds like you’re asking specifically about UI.Pages. If so: it does nothing other than draw little lines on the right edge of the screen, one of which will be highlighted. You initialize it with two numbers: pages = UI.Pages.new(selected_page, num_pages), then you update which little line is highlighted via pages:set_index (or pages:set_index_delta, which makes it easy to map the delta from enc(n, delta) to your page). You can read out which index is selected via pages.index. That’s it, that’s the whole thing. Typically what you’ll do in parallel is change what content you render on the screen based on pages.index. Perhaps you’ll have an array of lua objects each representing a screen, and you’ll use pages.index to look up which one you should delegate to for rendering. Maybe you’ll have some other system :woman_shrugging: up to you! If you’d like, you can take a peek at how my app does it here: https://github.com/21echoes/pedalboard/blob/master/pedalboard.lua#L115 look for usages of pages (the UI.Pages instance), pages_table (the array of lua objects that are the actual page look and behavior), and their related functions (current_page, pages_table[i]:redraw(), pages_table[i]:enc(n, delta), pages_table[i]:key(n, z), etc.). I also read the Passersby script a lot when I was first getting the hang of it – It does a lot less separate-classes/abstraction stuff than mine, and may be a bit easier to follow.

“Shifting focus” is more typically done with UI.Tabs, which imply more than one on the screen at a time. It’s superficially similar to Pages, but rather than just a number for the active one and a number for the total, you give it an array of strings that render as titles for separate horizontal sections of your screen. But, like UI.Pages, that’s… about it. How you choose to use tabs:set_index or :set_index_delta is up to you! My app does it with K2/K3 so I could use E2/E3 for controlling the content of each tab, but different apps take very different approaches. UI.Tabs also has no notion of the content “inside” the tab (other than the title), so you’ll, like pages_table, likely want some parallel data structure that manages the tab content and behavior. My approach was a render_tab_content(index) function which calculated the bounds of the tab and delegated rendering to other objects, providing the x_offset and width to them to alter their implementation as needed.

4 Likes

Hi @21echoes thanks very much for the detailed response.

I think the page widget might still be useful. I’m probably over-complicating things terrible, as I’m really surprised how much code I’ve generated, with relatively few controls.

I think, having got the core functionality working, I’ll go and do some experiments with just the UI, and see if I can work out a system that’s simpler.

I’ll also have a look at Passerby, as you suggest.

Thanks again!