#Flipper WIKI -- creating User Interfaces

23 messages · Page 1 of 1 (latest)

wary fable
#

I'm trying to document everything I've learned writing apps & making videos for the Flipper Zero. Documentation is currently lacking (it's still a 0.8x product), but at least there are at lot of samples and source code to look at. The UI API code seems stable, so probably not huge changes between now and v1.

I'm sure I've got some stuff wrong, and sadly GitHub doesn't really allow for good community editing, but feel free to ping me and I'll try to keep it up to date.

I'm not really sure where is the best place to have a wiki for Flipper Zero, so I created one off my flipper-zero-tutorials repo?

I plan on covering many topics... but right now it covers the basics on ViewPort, Canvas, View, ViewDispatcher & SceneManager.

Probably next is to populate the Modules page?

https://github.com/jamisonderek/flipper-zero-tutorials/wiki/User-Interface

GitHub

I will use this repository for my Flipper Zero projects. The various README.md files should describe how to use the files on your Flipper Zero. - jamisonderek/flipper-zero-tutorials

glacial robin
#

I might be able to help fill out some of the modules. I’ve been exploring them on my own out of curiosity. For anyone else curious, the GUI link provided for an overview of that section is a good start, but some of the modules mentioned are already deprecated from what I’ve seen (like I think we use dialog_ex now) and that list isn’t comprehensive

wary fable
#

GitHub really lacks sharing in the wiki side of things, but if you send me text/images I can add to the wiki.

wary fable
#

@glacial robin I added "TextInput" to the https://github.com/jamisonderek/flipper-zero-tutorials/wiki/Modules page to give you some idea of what documentation I was thinking of including for a module. Let me know your thoughts & which modules you wanted to cover.

GitHub

I will use this repository for my Flipper Zero projects. The various README.md files should describe how to use the files on your Flipper Zero. - jamisonderek/flipper-zero-tutorials

proven cedar
#

@wary fable this wiki has been super helpful so far!

wary fable
proven cedar
#

UI and GPIO are what I'm working with right now, so I don't have any requests outside of those at the moment

wary fable
#

My video this Saturday is on adding an I2C temp sensor to the Unitemp app. I think it will cover how to read data sheets, etc. (I haven't created the video yet).

proven cedar
#

yeah, sounds good to me

proven cedar
#

If you don't mind, codeallnight, can you take a look at my question here when you have a moment: #software message I've been reading through your wiki, some other sample code, etc., and I feel like I'm missing some critical detail but I don't know what. Much appreciated.

wary fable
# proven cedar If you don't mind, codeallnight, can you take a look at my question here when yo...

Do you still have questions, or does it make sense now?

Consider something like (X,Y) coordinates. You wouldn't want to render while you were in the middle of updating the coordinates, because you would have an invalid combination. (Or a temp value and an enum that says "C" or "F".) Typically access to the model is protected by a mutex (to ensure mutual exclusive access) & the other code that wants to update it has to wait until the view (or whomever is using the model) is done with it.

proven cedar
#

I understand the purpose of a model when you use its mutex functionality, the mutex protected access makes sense. What baffles me is the way its set up makes me think that I'm still missing some important detail since its a very specific and convoluted mutex setup and not really a generic one.

The draw callback is the only one that uses the model member of the view struct. Every other view callback uses the context that was set. None of the callbacks include the View* as one of the called arguments, and draw has no access to View* or context. So if, i.e. input callback, needs to modify data in the model (which at least one of the callbacks outside of draw likely would), you need to have View* somehow part of your context in order to access the model. If your draw callback needs access to any common data but doesn't necessarily need a mutex, you still have to use the model acessors. Since you can allocate a model without a mutex, it seems really strange to still enforce that opaque access.

My confusion is basically that the draw callback enforces the use of model as its only context, whereas every other view callback has to take care to be able to access its View* in order to access the model member so draw can update. That absolute enforcement right next to letting you shoot yourself in the foot is why I'm wondering if there is some use or access paradigm that I'm missing. But if that's how its supposed to be, then, I guess my understanding is correct?

I currently worked around what would be copying the same data by just making model a pointer to a pointer, assigning it the main struct I'm using, so now everything is happy (the application has no need for the view model mutex since its pretty static data, just over multiple views/scenes).

wary fable
# proven cedar I understand the purpose of a model when you use its mutex functionality, the mu...

Do you have a repo you can share?

I agree that it's confusing that most places we get the context of the app, and we do...
with_view_model(
context->view,
MyModel * model,
{
// We access the model here.
},
true);

and then the DrawCallback's second parameter is not a typical app context, but instead is the result of invoking view_get_model(view). I think this is to discourage a design pattern where the draw callback accesses properties outside of its data model?

#

Also, if you are having your model just contain the pointer to your main context (and have good reason for doing so) then use ViewModelTypeLockFree as the second parameter of your view_allocate_model call, so you don't have the overhead of the mutex.

proven cedar
# wary fable Do you have a repo you can share? I agree that it's confusing that most places ...

Not immediately, I can share later, but also I wasn't sure if it was using the model the right way to begin with. Looks like it might have been copy/pasted from other example code, which, no judgement from me, I've absolutely done that lol. I'm just on a kick to learn the flipper API to maybe churn out something neat.

But regardless, based on your feedback, sounds like there isn't anything critical that I'm misunderstanding

proven cedar
# wary fable Also, if you are having your model just contain the pointer to your main context...

The code I'm working with was already using LockFree, which is why I have zero issues just moving it to a ** and using that to point at the main struct that. Like I said, the fact that you don't need to use a mutex, but still have to use the accessor, was making me question how it should be used, if there are any gotchas of not using a mutex (e.g. I don't think draw callback was set on a timer, doesn't need to be, and its really only the input callback that would affect anything that would draw.

#

I don't have a good reason to do one thing or another, frankly lol

#

just trying to simplify access and reduce memory footprint

proven cedar
#

In any case, I do appreciate the feedback/help/conversation. Thanks!

wary fable
proven cedar
#

I'll take a look when I can in the next day or so.

I still need to write...
Yeah, there is a lot to document there lol. Good luck! I'll absolutely make some contributions as time goes on if I come across any use cases that arn't covered.