 All right. Hello, everybody. Let's see, Paul. Will Titanon have impression that its clock is running a bit fast after some hours? Yeah, it definitely does. A lot of circuit Python devices, if they stay on for a long time, the clock will become less accurate over time. There's a Adafruit Ticks library, which can try to help out with that, is my understanding. I'll pull it up here in a minute after I do an intro. I think that library can try to help, but I do also think it's a tough problem. If you have access to the internet, then you can fetch the time from there to get yourself updated. But if you don't have access to the internet, then it will, unfortunately, I think just drift sometimes. But yeah, so how's it going, Paul? And see Grover, also Beata over in the YouTube. As more folks are coming in, let's see here. It looks like I didn't actually check the sound of the mic, but it looks like we're good. Let's minimize this and make sure I can see the chats here. So quick introduction. Hello to everyone. If you are new, you don't know anything about what we're doing. My name is Tim and I go by Fumiguy on Discord and GitHub. And in this stream, we will be working on circuit Python related things. Typically the stream deep dive, or I shouldn't say typically, but at least as the stream was created, it was the deep dive with Scott, the lead developer of circuit Python, but he is away right now on parental leave. And so I'm filling in. And so we are working on circuit Python related stuff. If you don't know what circuit Python is, though, I think I have my screen up. Is that right? Yeah, we switched over to this. So we have my screen up. So this is circuitpython.org. This is where you can learn more about circuit Python if you are interested and want to dig in a bit. But basically we're writing Python code that runs on these tiny computers called microcontrollers. There's a bunch of them listed out on this downloads page here. And what you can see is there's all kinds of different shapes and sizes of these things. Some of them are, you know, round with alligator clips. Some of them are this feather form factor, which have a bunch of ready made feather wing add-on devices. Some have keys built in, some have screens built in, e-ink screens, all kinds of different shapes and sizes of these microcontrollers. The thing that ties them all together is the fact that we are writing Python code to run on these microcontrollers. If you are interested in getting involved in circuitpython, it's an open source project, so all the development occurs out in the open on GitHub. And we also collaborate on the Discord, so I encourage you to join us over there if you are interested. There's also a contributing link on this page here, circuitpython.org, slash contributing, or you can just click the link up at the top. This will take you to all the open pull requests and open issues, including all the good first issues on the open issues side over here. You can filter by good first issue, and this is a pretty good place to start if you are brand new and want to get involved. These things in the good first issues, they tend to be, you know, not requiring a whole lot of experience with circuitpython. Even folks that aren't necessarily having a lot of experience with programming and maybe even haven't used circuitpython ever before can still tackle some of this stuff. So that's a good place to head if you do want to get involved. Another thing you can do, I did mention circuitpython is an open source project, but it is primarily funded by this company. This is their website, Adafruit.com. So if you want to help support the project but not necessarily get involved in the development, what you can do is head to Adafruit.com and purchase hardware from them. Adafruit is a hardware and software company based out of New York. They sell microcontrollers that they create and manufacture. They also resell other people's devices. They also sell sensors and lights and speakers, widgets, all kind of things that you can plug into the microcontrollers to interact with from this Python code. So if that kind of stuff sounds interesting to you, if you're already buying that sort of stuff, definitely head to Adafruit.com. Check out what they have. And again, if you do purchase hardware from them, you are helping support circuitpython and all of those of us that they pay to work on the project. So jumping into it tonight, how's it going, Tammy and Dexter and also Dave Odessa over on the YouTube. Good evening, folks. Well, evening where I'm at, whatever time of day you're in, that's cool as well. So jumping into today, what I want to work on is kind of picking up where we left off last week. I worked on the tab layout last week. We had a bit of a stumbling block where I had noticed that I accidentally deleted it and we got it back up and running last week. And so I kind of want to pick up where I left off there, which is implementing the touch interaction. I spent a bunch of time this week on PyCon stuff. So for folks that don't know, last weekend was PyCon US out in Salt Lake City. And on Monday and Tuesday, specifically, they had the sprints out at PyCon. So folks that attended the conference could go to the sprints and our very own Melissa and Katny, who also work on the Circuit Python project, they were out there running the sprints and we had tons of new folks get involved and contribute to Circuit Python libraries. So that was really, really cool to see. I've been doing reviews and stuff for that over the course of this week. And so I didn't get much done on the tab layout because that stuff definitely took priority because we had all those new folks and we're always looking to get new folks involved, right? That's kind of the one of the most important things we can do is grow the community. So I'm getting back into the tab layout stuff this week. I'll be doing the touch interaction. And then we'll also look at an example. Paul is here, Paul SK in the chat. So I'll mention, you know, early hug report or I think I gave a hug report last week, but I'll probably have another one. So last week after I worked on the tab layout, Paul actually in the chat here grabbed what I had done and kind of ran with it a bit. And so Paul has posted a couple of examples of using that tab layout over in the Help with Projects channel, I think, on the Discord there. So if folks are interested in seeing this layout taken a little bit further than what I have done so far, head over to that Discord in the Help with Projects and there's some pictures and other information that Paul has posted up there. So thank you for doing that. Thank you for sharing it. Thank you for playing with it. That is all very much appreciated. I'll probably pull that up and we'll kind of reference back and forth that because I'm going to be implementing some of the same sort of touch stuff. So I'll take a look at what you've done and how you've set up some of the sensors and things. We'll do our touch and then I'll maybe also try to connect a couple of things together and build sort of a simple layout or a simple interface with a couple of different live updated data things on the screen. Oh, order you did. Let's see. Some days ago with Adafruit got delivered at your son's address. Interesting. I have noticed Adafruit, it does seem to keep the addresses. Like if you go into your profile somewhere in there you can manage your addresses and some of my really, really old addresses that I haven't lived at in years are in there as well from when I ordered projects, products I should say in the past. So that's one thing you can do is if you check in your profile somewhere there should be like a manage addresses. I don't recall the exact place but I do remember seeing the list of all of them and being able to kind of edit or delete them. Let's see. Question for, let's see, we have both chats? Do we have both chats on the screen, right? Yeah, okay. So question over in the YouTube chat from Beata to Tammy. The 8051 based board and then they're asking is that for real? So I'm not sure, I guess maybe Tammy showed something like that but that question is over there. So let's get this plugged in. Let's see, I think I did the development on the Titanic but we also were much more mindful about not just doing the development only on the device. We also pushed it into the repo last week to avoid having another mishap, right? So I have the repo open here which is with the latest version. This is where I'm going to start from. But I do think I have not put it on this PyPortal yet which this one is the regular PyPortal, not the PyPortal Titanic which is what I was working on last week. And there's not a great reason for why I switched. I just happened to already have a sensor plugged into this one and ultimately I want to read from the sensor and put it on one of the tabs. So I figured I'll just switch over to this. This will also give me a chance to test out sort of the new device workflow, right? Like coming from a device that didn't have this library does it work as I intend which is always a good thing to try out especially after you've been doing a bunch of development. You might have solved some little one-off bug about a requirement or about a certain version of it or something. You might have solved that and just kind of filed it away to take care of later and then forgotten about it. So jumping to a new device is always good while you are in active development to make sure that your whole process from getting it loaded and getting it running and making the example work actually does work how you think it does on all devices. Not sure I know what you're referring to. I haven't done any 8051, maybe somebody else. Let's see here. So we're going to, should I delete this? See now I'm scared to delete things. So what we're going to do is actually rename this and though I probably don't need it too old. This is a little trick you can do except for that's not actually how you do it. You want to rename this. Just rename this old or real or whatever we want. We could put a version number in it if we wanted. It doesn't really matter what we name it as long as it's different than it for display layout. And then probably we can refresh this to get it to update. Yeah, there it is. So we can paste our one with the tab layout in it. We want the whole folder. There it is. Well, let's go just the folder by itself. Let's see here. In my order case it was my wish. I gotcha. Gotcha. Matrix portal and a USB 32 S3. I grabbed one of the S3s but I haven't. I think I've actually set it up yet. Matrix portal is always fun to play with though. Let me load this real fast. Nope, it doesn't load. All right. So we can grab the example as well. Did I paste it? No, I didn't paste it yet. Copy that. Put it on our device inside lib. Wait for it to copy and then close lib. And I think we'll just see what's inside code. Do I need to keep this? Oh yeah, this was a test for continuous mode on the VL6180. I don't think I probably need it. But I also not hurting for space or anything I don't think. So we'll keep it and delete it later if we ever end up hurting for space. Grab the test. To start with we're just going to make sure this is actually working as intended. Probably I'm missing some assets like the... Okay, right. So we need the newest version of image load for one thing. Which has the tile grid inflator inside of it. It doesn't matter too much where we're at here. I'll go up one though because that seems weird to do it inside magtag. Circuit install. Ready to install. Already installed. Update. Such option update. Can you do a... I feel like I run into this every time I try. For some also on an old version. Update all modules. Does anybody know if the current version, the newest version of circuit allows you to update a single library by its name? Should update no matter what I guess. Uninstall which I guess I could do. Okay. I really want to uninstall either. I think honestly this is how I ended up deleting my working copy of display layout. Maybe was running this update all. And I'm thinking maybe that deleted my modified old version and installed the current actually published version. Kind of traced back through some of the stuff I did. And I think that's probably what ended up happening. In this case I don't have anything special inside of it. So I guess it's okay to delete. That's MPY ones anyway. Mouser didn't want to sell the S3 box. Oh interesting. Weird. That's going to probably get me a few more times. So next thing is we don't have this BMP slash test bitmap 7. Which those are the assets I was talking about before. I think we'll just, they should be checked into here actually. Yeah. We should probably rename those or remake the PR. That's the other thing I think I'll be trying to do today is if we can get the touch working. And maybe one more example. An advanced example. I like the idea of keeping the simple example. But I also like the idea of having one that's more advanced that really shows you how to like update text on each of the different pages and stuff like that. Which is all the stuff that Paul figured out. Again on those ones that he posted over in that help with projects. It's also all on GitHub if anybody wants to see the code. I'll probably pull it up here in a bit. Let's see here. I think it's just in the root, right? I think we can just paste that. Could be there, yeah. Our grid has no attribute bitmats. We have an old version of CircuitPython. Because this, the tab layout, it takes advantage of a newer piece of functionality inside TileGrid. Which is a property that allows you to update the bitmap. Which was a change that I had put into the core in order to support doing stuff like this. It is merged now, but it is brand new. So if you don't have like absolute newest type version, I don't even know if it's in the beta, to be honest. When was this beta? Check the release notes. Ten days ago. I'm not sure. Let's give it a try. Double tap reset to go to bootloader. Paste on the new one. Okay. So that got it working. And it will basically cycle through all of these. You can tell I kind of did some of this on the PyPortal Titano. There's actually, there's some of the text is running off the side there. But that's okay for now. The actual tabs rendered well, which is nice. They, I think they're set currently to always occupy a quarter of the screen maybe. So it divides evenly on this screen as well as on the Titano. It will make the most of the amount of width that it has. Which is kind of cool. So this is working. So let me, I'm going to take a look at what you came up with, Paul, and see, maybe take inspiration from there or just see where you got to and then kind of implement the touch the way that I was thinking, which I haven't planned it out fully, but I'm thinking about doing like a process touch function on tab layout. And then you'll pass it, I think we'll pass it the event, touch event, and then inside of there it will do, nope, different branch maybe. I think we can, how did I, I think I find this last time this way. Oh no, we don't have, so they changed this button I feel like it doesn't, I didn't get to that before. Yeah, I noticed this before, you used to be able to click on this 13 to go and see the 13 forks. Here we go. This is the page I'm thinking of. You used to be able to click this number and come to this page. See, what was the tab layout? Here we go. Okay, I just had GitHub name wrong. And so let's see, did you end up with changes in here as well? Looks like it, couple maybe. Yeah, pretty happy with the way it came out. And the really cool thing about this is that you can, you can fully customize it. So like, I think these green ones with the gray and the black, I think these look pretty cool, but you could just easily do, you know, white and pink and gray and black and blue and red. You could just easily make these whatever you want. They don't have to be rounded. They could be trapezoidal. They could be, you could get really fancy with it. Let's see, made some mods. Tab dims. I did read a couple of your message. I don't, I may have missed the one about tab dims though. Mod and draw tabs. Let me check that out. Is it just store? Okay, list with dimensions. Okay, so this will be the pixels, basically. Well, is it pixels? Maybe it's not pixels. So X, Y I guess is probably pixels. These ones may be in tiles instead of pixels. Not certain. At the end. Was over two only. There will be pixels. This, this multiplied. Well, yeah, yeah, we'll get you to pixels. X over two. Y equals zero. What does the difference here do? Y equals zero. Probably would have to play with it or add some prints to get a clear idea. I think, I'm not sure if they need to be, oh, there's difference here too, actually. Trying to think. It may be possible to not need the, because this would check for the first one, I think. Let's do the first one differently. It may be required to though. I haven't, I haven't sat down and actually done it yet. So it's very possible I ended up running, that I will end up running into whatever the reason for it was. Get tab dims, which gets the length and turns none. If it has none, have number. Have dims. Just clamping the range. Make sure it's actually inside the range and then return it. Use the info to check if a touch. I gotcha. I may take a slightly different approach. We'll see once I get into it. I think what I'm... Maybe I'll wrap back around and end up doing it this way. My first thought was to basically check the Y based on the... What is it called? Oh, did we not make a height? I thought we made a height. Maybe I forgot to put the height in this time. Oh, I guess what I settled on was to manipulate the height by using the... Not that, what I just highlighted, by using the sprite sheets. I think maybe that's what I came to last week, actually. Yeah, this is coming back to me. I think I talked it through on the stream last week and decided the sprite sheets... You can always get fine-grained control of the size just by using a bigger or a larger sprite sheet, taller. And then it could inflate itself bigger. I think there's something nice in the simplicity, though, of not needing to do that and having it just be derived from the sprite sheet experience that clicking the... Clicking on the tab, the Y value often will be more than 24. Ah, okay. So maybe we'll make a... Yeah, that's a good point, though, especially about fingers. We should... Well... Is this one calibrated? We need... But yeah, that's definitely a good point. It does... Especially if you are using a finger instead of like a stylus or something. It has kind of a big range where... But technically it's registering a single point and it might not be like the exact middle of your finger or anything like that. So it would be good to give the user a little bit of a buffer down there. A little bit of an extra space where, like, if they touch on that space just touching on the tab. Honestly, a lot of buttons are done that way in like mobile interfaces and stuff. The actual touch zone sometimes is just a little bit outside the visual. That way you have kind of a bit of leeway there which I do think is a good idea for sure. Okay, let me take a look in the actual example code as well because the cool stuff Paul has done is put in, like, actually reading all these temperatures and things. Looks like this is the newest one here. Reading from sensors and oh yeah, we'll have to clean this all this stuff up here, up as well. But connecting two different sensors, I think at least one, one or two over I2C and then maybe reading one from the onboard too? Let's see. We'll do one from the onboard either way though for sure. Oh, and reading it looks like the SD card as well maybe or the status. No. SD maybe? Oh and the time. That's right. You have an RTC on there. I also forgot about, you got a lot of stuff going in here. This is really cool. And check it from NTP as well. So internet time and I think RTC. There's our touch screen setup. If you want rotations. I wonder if we should add rotation to the initializer here. That way the user could specify the default orientation calibration values and size values, but then also just pass the rotation degrees like 90 and then have it handle all these different ones internally. That might be kind of cool. That's like definitely outside the scope of this project, but might be kind of a cool thing to do. It would take a bunch of the boilerplate code out of user code like you wouldn't have to put all that stuff in CodePy anymore and instead you could it would end up living inside touch screen the library. RTC or NXT, SD card not the onboard, so external temperature sensor. Nice. See, I feel like 8051 was a great device for its time. 2022 is no longer. Yeah. It's in everything USB floppy disk controller, power manager, controller, old laptop basically half the stuff in my frustrated boxes. Yeah, I got a got frustrated box hanging out somewhere as well. Oh, nice. I like your little helper for updating the basically looks like updating the background of a group pretty much. I mean you could do any kind of image, but my guess is this is probably being used for the backgrounds. Pop that image in there. Nice. Group, group pop. So it's going to remove the old one. One thing you could do if you're interested is because we now have the ability to update the bitmap on the tile grid you could actually keep the same bitmap inside the group and not use pop and instead just create a new on disk bitmap or regular bitmap if you wanted to do load it to memory as well that would work the same and then you could just change the bitmap on the tile grid and you wouldn't have to remove it from the group here and you wouldn't have to add it back to the group here. That's one of the new things with tile grid, but it is brand new. So if you do want to do that you have to have well I guess if you're using the tab layout you already have to have that super new version anyway. Oh and it was in this, right? We downloaded beta 2 and we did get the version that allowed us to do that updating bitmaps. I don't know if it's necessarily I mean I guess it would save you creating new tile grid so it probably will save a little bit of memory over time I don't know if it would be a huge deal or not maybe not but possible optimization code will reconnect to the sensor oh yeah yeah you saw I saw that when you mentioned that in the chat the other day that's actually that's really really cool one of the nicest things I think about Stemma is the ability to kind of like hot plug back and forth and the code that you wrote that kind of connects automatically and then also retries the connection automatically that's actually really really cool I think the way you can like unplug and re-plug stuff and have it live just keep running while you're doing it like that is super super neat so again thank you for doing that and sharing it I think that's actually a really cool thing which can add to any of their projects that use Stemma stuff connect up the temp sensor there we go so this is our external temp sensor over I2C here's our RTC is also on the I2C bus read a temperature and put it into the label on page 4 hit date time and put it into the label on not day 3 on page 3 click touch in page I like this kind of stuff too the way you did debug prints like this I do this a lot in my in my work code as well where I'll put all of my like troubleshooting debugging developing print statements inside these if checks like this so you can turn them all on and off at once there's more sophisticated ways with like actual logging libraries and stuff but I kind of like this is like just a step up from print debugging and it's a really nice step up I've found I don't necessarily need all the real bells and whistles of the logging libraries and stuff also the recent log4j stuff made me pretty happy that I never started using fancier logging libraries truthfully but I do use logic like this with an if statement and a boolean check for touches there's our main and so here's how it's doing the reconnection because you have a while true and then checking for the devices to exist connecting them if they don't and then because this is inside the loop it will be happening over and over so if they get disconnected it will just notice it try again and eventually if it gets plugged back in it'll notice it and actually reconnect and start updating its label again nice good job on this yeah this is really cool if you're interested I think maybe wait until after my PR is in but if you're interested I would say like totally PR this to the to the Adafruit copy the Adafruit fork of this library it'd be great to have like a fully fledged example like this you know it's specific to the to the exact devices you have but folks can swap that out pretty easily especially that's another nice thing about all the I2C drivers are you know kind of like they have drivers that are very very similar so set up tends to be the same if somebody else just had like a different temperature sensor and a different RTC they could probably just swap the import swap the initializer functions and like beyond the road ready to go even switching it to a different kind of sensor would be pretty straight forward they'd have to change a little bit more code but like you know they could swap it to a distance sensor or a accelerometer or something like that been including it as a plug and pray I've been including that as a default Kindred spirit print debugging and using a helper method such as printd nice which code was the hotplug biata that's it's inside of here it's basically to kind of show the exact portion of it it's inside of main let's see we had where it was main down here I'll link this as well we're in the youtube chat there and then it is so down inside of main well so these are these are important these connect temp sensor function and connect RTC function this is where the actual like logic to try to connect to the device happens and then main here has the loop inside of it and then inside that loop it has sort of this top section here which is basically checking if the RTC is already plugged in and if it's not that's when it's calling connect RTC same thing for the temperature sensor here check if it's already connected and if not rather if it is then get the temperature from it but if it's not then run the connect function so that's kind of how the logic for that reconnecting on the itc bus is working here and then you could of course like if you look inside those connect functions you know you could of course just swap out you know whichever sensor you need to set up here and honestly the same logic would apply to pretty much any itc code eyeball cp yeah yeah for sure alright so I'm gonna take a stab at this as well doing the touch input I think I am gonna do my api a little bit different I'm gonna try to take a bunch of the logic out of codepie for at least the logic for managing the tab touches themselves I think what I want is in here to say well first of all we're not gonna be able I mean we could do it but we don't for some reasons we don't want to sleep anymore basically we could talk about it more once I have some of it in but basically we won't be able to listen for touch events during this time that we're sleeping and we don't really want this thing to run automatically anymore anyway because instead we're gonna use the touch screen to change it this was mostly just as a demonstration of the rest of the api before the touch was actually implemented what we will do though is set up the touch screen which I will actually just snag from yours I think I recognize this as like the sort of stock touch screen example stuff we could copy it from the touch screen library itself as well if we wanted I think where do we want to put that I think we'll go under display stuff and I'll keep all of these for now but we are gonna stick with the standard orientation which will just be landscape hopefully in the orientation it's sitting on my desk and if not then we will actually go back and change it so that it is in the look in the orientation I have I'll keep default calibration screen height yep we already have these you can actually if you're interested you can do display dot width display dot height here you don't have to you can also hard code them but they're on the display object and you could also just do board dot display shouty dot width and height that works as well right screen width okay so this should set up our touch and then we're basically doing down here I think I will check for I'll do the first check for like get the touch events and see if there are any but then I think I'll just pass that event object or I think it's a list actually down into tab layout I'm gonna go like this one touch equals touch point if touch and then in here so if we did get a touch then I'm gonna go test page layout dot I really want to call that I think um process touch handle touch handle touch maybe handle touch events even more specific I don't know maybe it's too wordy handle touch events we'll pass touch in here oh I don't think well it's a tuple not a list it represents a single touch event it's not a list of touch events multiples although you will get one each frame if you keep touching um and then I think it's a tuple like a three tuple I guess maybe for x y and then um pressure if your screen has pressure so we're gonna pass that in there and then of course we actually need to write that function on our tab layout because we haven't done that so inside lib layout this one tab layout we're gonna make def handle touch events and then this will be self and touch event touch event this is a tuple containing x and y coordinates of the touch in indexes 0 and 1 and then we're not gonna do anything with index 2 tuple returns uh I think it just returns none need to return something could return true or false I think for now we're gonna try return none and if we need to if we come up with a good reason to return something later then we'll add that in as well uh check if the touch event is on the tabs and if so change to the touched tab so uh we know that touch event will not be none because we handled none out here although we wrote our user code this way maybe we should still maybe it's probably a good idea to still go ahead and check for none inside of here just in case somebody writes their user code differently um and they just pass in touch point without checking it for none I think we should support that as well yes it's a tuple nice uh why use let's see James Seth uh thanks for joining us here in the chat and watching along I assume you are why use print with formatting instead of sys.std out for debugging when avoiding logging modules and packages yes it would be application dependent but in most cases you don't need formatting um I don't I can't say that I have a very specific reason I would say I don't have really any experience with sys.std out so I've never used that so just familiarity with print um and formatting um I would say is probably the reason that I reach for print most often as opposed to that um the other thing I would mention is I don't know if uh I don't know if circuit python does support sys.std out that looks like it does I don't know how you use it though you just call right or something like this yeah I don't know where the five came from oh five is the length yeah five is the length well 12 is the length this time but interesting what's the uh what would you say is the advantage doing it that way application dependent I'm just not familiar enough with in fact I think this is honestly the only time I've ever used sd out is right here you saw it so I'm not familiar with like what would be the uh the main upside to that uh okay so if we have an event then we are gonna check the y if touch event y which is actually one because it goes x y and then pressure if touch event one is greater than zero I'm not sure we really need to check for that but we might as well to make our code real nice and explicit greater than zero greater than equal zero actually and uh touch event y is less than equals and we yeah we ended up without a tab height right so I think what we'll do is is that true oh no we did actually we got a tab height but it's just comes from the bitmap so we can go ahead and use it less instruction cycles and no formatting I got you I got you so it runs faster potentially especially if you have it in like a super quick loop or something which is what our I mean our main loop is is that basically for sure uh let's see this is just mad because a pass and then I think it'll be yellow because we could still mad what is this oh right right self we go and then I it'll reformat this right simplify or whatever yeah I don't this is one a pythonism that I don't I always forget to I know it exists but I just don't code it that way by by default basically it just doesn't it you know whatever it is my subconscious it doesn't come out that way though like three if statement with the one you're testing in the middle it is nice though I do like it it's cool syntax um yeah maybe we'll give it a fudge factor here let's try it without and see how it goes but then maybe what we'll do is like self dot touch leeway or something like that and maybe we'll make a variable that you can set if you want let's try it without first though so if if we if the why is outside this range then we don't care about anything else we know we're that they're not touching on the tabs um so we're just not going to do anything with the touch event uh which means we won't go inside of here we'll end up down here and it'll just return none basically but if we do get inside of here now we want to basically check the x to see which tab it is touching and since our tabs are all dynamically generated their size that's true because we have tab count and yeah all the tabs their width and their x location is all generated dynamically as you add them so if you add four tabs each one will take up a quarter of the screen as best as it can there is still some restrictions based on your tile size um the final size that it ends up has to be a divisible evenly by your tile size but it will try to use up um the perfect sort of division of the screen so if you have four tabs it'll try to use quarters of the screen three tabs it'll try to use thirds um so how do we want to do that we could so one thing we could do is we could just check on the the tile grid itself is that what we do want to do though the other thing we could do is just divide the x by the tab count and I think that gives us the index of the tab that got touched so let's just start by adding some prints maybe print um touch event x which is actually zero and I'm also gonna print um so the real pixel value and also I'm gonna go touch event zero over tab count see if that gives me the index like I'm thinking alright so let's start with that how do we have there the chat's actually covering it up a little bit isn't it we'll just scoot it for now need to probably play with my scenes a little bit I try to make the chat a little bit transparent which helps some but it does take up a lot of the screen maybe I'll shrink my actual screen so anyway this is good for now so let's do some touches here oh okay I know I definitely done my division logic wrong we are getting pixels uh let's see I would want to divide yeah I don't want to divide by the count I want to divide by the screen width over the count yeah and then maybe add one also I'm not sure I'm a I'm a I'm a guess and checker with math honestly I mean I could write this out and figure it out for sure without guessing but like it's so much faster to just guess and see what it does and if I'm wrong then add one yeah why are we mad I have enough parentheses this needs to be in here so first divide the display width by the tab count and then divide the x of the touch coordinate by that by what we got from that x minus pixels equals screen width there we go 0 1 oop we do eventually get 2 the calibration does seem okay actually the first one seems to work pretty perfectly the next one is pretty far off sorry you can't really see where it's at very well basically we're still on one here we don't get up to 2 until right there let's take a look at what some of these values actually ended up as because we should have so the width of the display is 320 the tab count is 4 which means each one of these should be 80 pixels so anything below 80 should give us 0 yeah and then we basically just don't get to 160 for some reason oh but this is only going to 240 I think I have configured this wrong maybe let's look in the touch screen what about the margins let's see what about the margin the edges of every tab they will technically still be clickable on the edges we could shrink it in some to make them not need to apply the offset x pixels over tab count minus tab width over 2 and a lot of log in it's like running on a very slow microcontroller yeah I will say like on the microcontroller print does take relatively long time like if you're actually concerned with the speed like with which you're reading a sensor or something like that printing inside the loop does actually take you know a considerable amount of time not on the human time scale right like it's still in the milliseconds it's still fast to us but if you do have prints versus if you don't have prints you'll notice a pretty good difference about how fast you can actually get your loop to run it does take it a fair amount of time to actually get it into the serial low power devices like IOT, every instruction yeah that's definitely true I'm just not like I'm trying to make the example which is meant to run off PC power and it's not necessarily meant to like survive in the field on a battery for as long as it can turning off the prints that's the best I think the best like during development you're going to be plugged into the PC so you have power you don't care how much power you use if you are making a thing that you're going to put out into the field that's where that debug if statement can really come into handy because like if you turn off all your prints you'll definitely be faster and and not only faster but of course not using the CPU and all the stuff to do the battery so somehow we have 240 here maybe I put width and height wrong or see what I did well we're in the wrong file for one thing what did I do here screen yeah these are backwards I think for my orientation obviously it depends which orientation you're in that's the one you would need it for I think these probably go with height but again I'm a guest in checker too so I'm just going to change it and see what happens this is another thing like I could go look at the docs but we don't get any now okay my finger was throwing it off okay so our 80 break point still looks pretty good oh yeah there we go okay 160 break point looks good now 240 yep there it is 240 came a little early honestly we're still kind of inside 3 honestly but that could also that could easily just be touch screen calibration and not you know undesirable just if we calibrated the touch screen a hair better we would be maybe not having a problem with that I will go back and do the calibration but actually I want to just chunk it in here and let's make it go right so we now have an index touched tab index equals this value which we put in here and actually what I'll do is so that I'm not doing the same math twice I will take that and actually put it below and then use this oops got to call it a day thanks Tim yeah see you Dave thanks for hanging out for a bit let's see why don't we use a touch response area for each tab we could we could I just am interested in trying it this way I don't know I don't have a specific reason reason one way or another necessarily just this is kind of the way that my brain broke it down by default I think it takes a mental adaption of the programmer if he was like you and I accustomed to the print statements and then moved to STD and see out yeah definitely and I mean it's also just a matter of like perspective and stuff right like I have worked super super high level like circuit python is on a microcontroller which in its very nature is pretty darn close to the hardware although obviously circuit python is an interpreted language running on a microcontroller so it is still pretty high level for a microcontroller I just am not in the habit of thinking about efficiency really because I've never made a thing where I have had to absolutely squeeze every ounce of efficiency out of it as a necessity so like I just don't do it by default and sometimes I have to go back and make things faster and I do that when I notice that it's becoming a problem but like you know it's just not the default way I tend to do things just because it's not ever it's not something I have a lot of experience with basically a lot of experience with needing I do a lot of web development and stuff and like the server I'm sure could always be made more efficient but it's efficient enough to do all the things I need so I don't really spend time making it more efficient I just spend time adding new features to it instead I think here we can just set our index right we call them showing page index equals touch tab index and that should change for us one thing that would probably be nice is if we add one more check actually maybe we should do that inside here I think it actually makes sense to do that in here if showing page index is not equal to the new index so if they are equal then don't bother setting it again I don't know that it matters really but that I you know I guess I just say that I don't go around improving efficiency before I have a need although I kind of just did there I suppose a little bit but in addition to being efficient though this honestly is more descriptive to me the fact that it has this if statement there now tells it conveys more about my intent my meaning the person who wrote the code it when I come back and read this it tells me more about what they were intending to do which I think is also nice person who tend to add debug format args method interesting then just call that debug format method I do something similar to that in Android I haven't done one on the Python side before but I have like a I call it util I think it is I have like a util.log nice yeah that is sweet okay let me try finger oh yeah that is really nice we could calibrate this and get it a little better with the this thing which the name is escaping me right now Stylist we could we could calibrate and we could get it better with Stylist but honestly it is plenty good for finger those feel exactly how they should when I am touching them oh yeah that is nice if you do have the function you can also swap out where it is going to so if you don't want it to print the console it could be going to a log or it could be sending over to a different server yeah that is good what do they call that encapsulation kind of because it is like letting the other thing care about where it goes the code that calls it just wants to call log this and not care about where it goes that is pretty nice alright so I am pretty happy with that I think I do like this idea of just having the kind of single function that will do this the way I have the math here it is not checking every individual rectangle which means it would look it would not match the visual if like I was talking about before if your tile size was not an even multiple or rather if the display was not an even multiple of your tile size then your tabs would end up being a little bit smaller each one of them and then the touch would actually still go outside of the tab a little bit but honestly I think I kind of like the idea of it divvying up the screen into the biggest like you know my approach to it is like you always want to make your touch zone even a little bigger than it appears especially if you are talking about a touch screen if you have a mouse then like in fact touch boxes make a lot more sense but if you have a touch screen close enough tends to be like what you want to go for because it makes using the thing a lot less frustrating you know if there was a little sliver in here of space where my tab wasn't quite the full width because of my tile size not being an even multiple or whatever like if you were to touch on that little sliver and it doesn't register anything like that's kind of frustrating from the user's perspective it doesn't they kind of just assume it's going to work if they touch pretty close to it so I kind of like this idea of dividing it out by the width and just evenly divvying it up the same way we did when we chose the width of those tabs alright so that's looking good I think I'll copy it back to the repo because we know that we want to save early save often if you will and I guess I'll probably just go ahead and do the test as well why don't I take a minute here to clean up the test too let's get rid of or do we want to have one example maybe we should have one example that's not the touch screen so maybe we should have simple test that uses no touch screen and just behaves like it did before automatically cycling the touch screen example which is this one, which does use the touch screen and then I think I would still love to have an advanced example that's like that one Paul made which actually is reading sensors and putting live data on each one of those different tabs another nice touch to that would be input on one of those tabs so like if we had a button on a tab and you click the button and it turns on the LED that's on the back of the board or something like that so like input instead of output from a sensor how's it going Gordy G thanks for tuning in I think I like that I think kind of tentatively I'm liking those three examples basically so simple test could actually stay how it is I think excuse me definitely don't want this don't need that just kind of go through here and fix the fix the comments while I go actually don't need to set that if we're going to use zero don't need this anymore if we're not going to have custom font I did test out custom font and it does work fine but I don't want to do it in the simple test which this is about to become the simple test we can finally get rid of this make a tab layout illustrate the most basic features and usage yeah let's do change these I think Shift F6 I think I can do so which one is which inactive is 6 so we're going to call this inactive tab sprite and then this one we're going to call active tab sprite yeah Naradok also with the debug function let's see oh this one didn't go yet there we go those are much better names colors we can keep this is pretty good eventually we're going to be needing to make a PR with this so why don't we start checking the actions black failed but it would have formatted it unused failed but I have files that aren't checked in so those are probably from that yeah 50 so we have 3 I actually have 4 I guess one of my ones checked in has a not checked in rather does have a license shoot rerun again line too long that's easy oh does this one something like that maybe docstring we made a docstring actually let me copy the page layout one because I just made the page layout much more recently and it actually has my stuff not K match because K match essentially made the the grid layout you created I'll say the core code for the grid layout and then I kind of refactored it into a class but the actual logic of laying everything out was all K match on that one for the grids I hope that organizes pages into tabs into tabs keep it short and sweet for now we can always come back and add more details as needed so some a lot of this will be taken care of let's let it run again and get the current list oh yeah much fewer well maybe not actually I just scrolled too fast was this missing class we'll have a lot of extra parameters we do still have X and Y but capital display int tab text scale size of the text and the tabs and eventually we could add more to this which I think it would be good maybe to specify whole numbers whole numbers one and greater are valid but I mean honestly probably you're gonna want to use like one or two maybe three if you're only using two tabs and you have a pretty big screen and you have really short labels but obviously there's not a whole lot of room so you can't scale it up too big otherwise it'll run outside of the tabs custom font this is a where does font it's yeah it's actually would be a union of bitmap font dot a couple of things I don't remember all of them honestly so I'm actually just gonna code it without a type for now oh actually they're all right here do you do the same one says these for Sphinx I don't remember this work for Sphinx let's see loaded loaded loaded let's see preloaded preloaded because you can't just give it a stream you actually have to load it outside loaded font object to use for the tab labels RAM string inactive tab spreadsheet now did I do string or yeah we load them inside image load we could use on this bitmap as well I think save a little bit of RAM the spreadsheet to use for to show for inactive tabs duplicate active well path of the sprite teach to show for active tab for the active tab since there can be only one hex or tuple color to use for the active tab label it's gonna complain that one's too long or not we'll find it if it does actually let's go duplicate again because we have inactive page down accidentally what's next inactive tab color so transparent indexes let's see tuple oh let's see tuple so single index or tuple of multiple indexes to be made transparent in the I didn't put the name in the inactive sprite palette active tab single index or tuple of multiple indexes to be made transparent in the active getting close let's see active tab count is the last one whole numbers positive whole numbers positive solid okay let's let pilot run again save this first what do we got now let me catch up on the chat while that's running as well how about the possibility to expand the range of usable characters like the degree sign look into so I haven't read the rest of this yet but right away my advice is look into is it Joey Castillo that made the e-book Joey well let me say whoever made the e-book I want to say that was Joey did work on like different fonts like Unicode I'm going to probably butcher the technical details honestly I don't know I probably have already have I don't know if it's actually Unicode or what but did work on being able to render other fonts specifically they were working on other language fonts it would work with other symbols and things like that as well like the degree thing let me Joey Castillo e-book what's the name of that thing open book that's it yeah yeah totally I don't I haven't looked into the details but I know that Joey did work on different font like here right here you can see they have I don't know what says Cyrillix or or something but Joey did work to figure out how to do different fonts like this so check into the open book project there might be some either inspiration to draw from or there might even be a library or some kind of way to do it already in there that could be relatively easily used from CircuitPython I don't know so don't quote me for sure but I do know Joey has worked on it some so that's a good place to start D1 Mini which is an ESP8266 to project a Spotify album art nice various European languages use a lot of accents yeah is there a pep we're using for doc strings I see you put the data type after I like it makes the code so much more readable yes I don't know if it is a pep but near doc is right that's a Sphinx formatting yeah for sure okay this should be done now right yeah okay oh wow we I wonder I should I wonder if I can I don't want to go too far but I'm going to indulge on a slight rabbit hole here can I set my max width code style yeah hard wrap it's hard wrap what we want we don't really want hard wrap do we I would like it to draw that line at 100 though okay yeah looks like it did going back actually this line being here will help me not angerpilot Blintery as you can 120 nice thank you what do we got now okay now we're finally cutting them down some let's see too many instance attributes that we're probably ignoring oh oh oh do I know u8g2 library for embedded graphics has a bunch of fonts with their licenses documented I did not know of that u8g2 with bdf fonts even look at that I could find yeah it's really nice to run that's one of the troubles honestly there's a lot of fonts like you can find a bunch of font files online that just don't have a license with them and like technically we really need to have a license if we're going to check it into the repo dang yeah they have a lot of them and what is this u8g2 that utf8 or is that something else oh is it an infinity on a chrome graphics Arduino library interesting never heard of this that's pretty cool thanks for sharing what's this one let me start this also so I can get back to it easily are there examples of all of these oh that's amazing as I was scrolling through that list I was like man I wish I could see each of these prayers have been answered right here it looks weird with the dark mode but that's just my dark mode these are images with white backgrounds there's a lot of fonts in here wingdings kind of newfangled wingdings that is awesome yeah Google fonts is a good place they have relatively permission permissive licenses typically and they post the license with it which is good but there are a lot you can find like lots of projects and stuff you search around where they use a font and they check it into a repo or something but they don't put a license with it Google font tends to be pretty good though as long as you like just check and see what the license actually says because I just I don't know for sure but I think there might be some in there that are like just licensed differently like some might be free for non-commercial but others you might not be able to use it for commercial or whatever of course if you're not making a commercial product then you do the one even if it was if it did have that restriction as long as you again you aren't making the commercial product I think the BDF are from X11 under MIT license nice I'm a personally biata excuse me I pronounced it wrong I was kind of close but I definitely did it wrong biata there we go personally a fan of the Terminus font I do like Terminus yeah I don't know if it's on my terminal or if it's inside PyCharm or somewhere I have seen that one though and I'm a fan of that as well too many instance attributes I we're probably gonna be ignoring that one I would love to hear the rationale I guess what I would do is go look this up maybe I'd be curious to understand the rationale on why 15 instance attributes by 12 instance attributes is too many what is that a sign of that just means our object is too complex what would be the proposed solution to that though like make a parent class and put half the attributes in it I mean some of the attributes in it but I don't I mean like if you're not gonna make two children classes at least then like make an apparent class feels like just splitting your code into two different spots for the sake of making this number go down which in my mind is making it harder to understand I'd be curious to understand what their sonor lint it's got to do with readability but I mean what are their like if I whoever chose this number like what would they tell you to do in this case like if we're using all the attributes that we have we can't just get rid of some so I the only thing I could think to do is put some on a parent class but then it's like I mean if you're not actually gonna make multiple children classes then I know it just feels like you're making the code harder to understand maybe easier to read because it's less of a wall of text in one file but harder to understand because you have to now look in two places to find get a full picture of the behavior I think we can do this down here actually right I like to put these at the bottom also I still have not really committed this to memory for sure I don't know if this is the right syntax yeah it looks like it no never mind did I scroll past it? pilot then colon then disable then equals too many arguments same thing here it's like I mean I could put a ton of these arguments into another object or a dictionary or something and then our number of arguments goes down but I I don't really think it makes the code more readable in fact I think it's the opposite makes it harder to understand I prefer ooh that was that was squeaky breaks um yeah we're definitely not gonna get down to anywhere near 5 from 13 I think we're probably just gonna be ignoring that one as well I'm gonna copy it this time though I think these are supposed to be like this maybe it's a way to reduce complexity you can define a builder class or an enum we don't have enum specifically but we have something like them basically using putty thing I've never actually had YouTube show me that thing before we have constants which you can pretty much be pretty similar to enums but we don't have specifically enums argument name inactive tab transparent indexes doesn't conform to hmm is this a length check or something 32 characters hmm I hate to just ignore everything but I mean I could take the word tab out and that would make it under the limit but I think it makes it harder to understand I'm pretty unwilling to appease pilot in situations where I think what it's suggesting actually makes the code harder to understand the whole point of it is to try to make the code easier to understand in a case like this is this a pretty wordy variable name yeah it is does it describe what it holds though yes I believe it does and it does so well hmm I mean I could do like idxs or something use acronyms on some of this stuff I suppose but it's it's kind of the same tradeoff in my mind really like we're making it less readable for the purposes of making pilot happy which just feels bad to me yeah I think in valid name I I don't know we'll see if anybody has thoughts on better ways to do it I definitely encourage you to leave a comment on the PR when I make it um I'm open to I'm open to ideas I'm not coming up with anything myself that I feel like makes the code easier to understand than it is now so I'm inclined to not change it and instead do the ignore but I definitely grant there probably is something that conforms that is better than what I have I'm just not thinking of it so anybody's got ideas please uh please leave a review once I put the PR up what is this access to a protected member ah yes do we really need that to be private I mean we may as well just make that non-leading underscore I think had content this will actually be pretty much the same oh that says grid but I copied it from page layout so it should really say page layout let me catch up what are the indexes for they are indexes in the palette they are they are they represent the index of one or more colors inside of the palette which we will then go and make all of those indexes transparent on the palette so that they won't get drawn on the screen there's no qa comment for most linters no qa oh you can do it by the number instead of the uh said the name what that is or grid power comes grid warning suppression no qa so this is like a separate thing it's separate from pylint but it still allows you to quiet pylint errors is that don't have an understanding of a warning suppression you have to install this where it's built in or it works with flake it works with pylint too pylint might use flake I don't actually know interesting I think in our case the pylint disables will work alright it's kinda cool though blocks the warning I don't remember exactly or I guess what I should say is I wasn't scrolled down and I don't know exactly which thing I said before you said no we have anything different here tab content the content for the tab typically a group the name of this tab should be shown it's none I think that probably gets us passing maybe oh we had a black fail but we after that other than reuse but oh no we have one more unnecessary pass probably I just put a pass when I first started writing a function and then yeah I never took it out I think I'll change this one to not use sleep just because if somebody does use sleep right here and then they go to start trying to add more complexity to this to read sensors to put them on different pages to handle button inputs to handle the tab touch inputs if they go to start trying to do this this sleep is going to trip them up a little bit so I think I will be nice and not kinda hand people sorta loaded bug waiting to happen and instead do previous change time is time.monotonic but now is time.monotonic if previous change time plus change delay is greater than is less than or equal to now do this and set previous change time to now so this is the exact same logic it's just not using time.sleep and instead it's using an if statement check in the current time was our problem oh change delay right I made a variable change delay this is in seconds we'll go 1.0 now somebody if they started adding more complexity to this other sensors and touch inputs and other things sleep would not be messing up their code let's run this and make sure everything works which it does not because I did not rename those files inactive is 6 it wants to restart on its own for some reason I'll help it out oh yeah there it goes there we go we got this and this one is still doing the auto advancing so yeah it'll just start running on its own there this is our simple test maybe one more thing I'll do is get rid of everything that runs off the edge before I do that though I am gonna have to take one moment here and run to the restroom and then I'll be right back I'll let this keep running here okay libraries using time.sleep aggravate people using async.io yeah that's true although if you are using async.io you have a relatively easy way to switch it to async.sleep whatever I don't know the right function but there's a function that works inside of an async function I guess a wait task or whatever so it's relatively easy to switch over but yeah you do have to make that switch whereas this way it would run fine inside of async this would be a good candidate for swapping over to async which I think will do at some point but I do want to get the basics out of the way and get examples out there for other people to start using and getting feedback on them before I kind of go the next step of the async.io stuff so I think let me just stick some new lines in doesn't really matter what's on these pages truthfully so the circle and the rectangle could both go down a little bit to account for the second line there we go rectangle doesn't need to be that far async.io.sleep but not for real time systems or critical requirements on the titano perhaps could use the full names like 3 or 4 yeah that's true even with I think scale 2 I think we're on scale 2 on the font if we scaled it down to scale 1 we could probably use the real names as well for 3 and 4 but I like the nice big labels even though they kind of limit us to only a couple of characters I think this is nice okay so let's copy it back again because I've made more changes again got formatted one more time again re-use is going to fail because I have stuff that's not checked in oh no actually this failed because of the bitmaps which I created so I get to choose the license for I'm choosing MIT but I do need to actually make the files you need to know the right format which I don't off the top of my head there should be some inside of here I made it this year and I'm going to copy that oh somehow re-use is not failing on those files actually could have looked into that earlier do these have licenses oh okay that's how I did it I should have put licenses in them even though they're not checked in alright so we're passing do we need to do anything else or are we ready to make the PR we have docs oh let's run build docs CD docs we have an alias for cp docs to run the sphinx command that builds is looking good let's actually load the page as well and make sure that it actually shows our new thing it's possible I forgot to add it might even be probable that I forgot to add it truthfully where's docs there it is why I don't know it looks pretty found to me did they just make this not work in Firefox can you not do these in Firefox anymore I did update my Firefox oh my goodness it's so old though this is 2013 alright go over the chat there brought me to an idea of inserting the new lines I'm gonna do that with the display yeah there's also if you're interested there is also inside of display text the library which is where the labels come from there is a wrap wrap nicely it used to be called wrap nicely maybe it's wrap text to lines or something there's these wrap text to pixels and then wrap text to character or something wrap text to lines this one does by characters these could help you add new lines automatically if you want to do it automatically instead of having to hard code them so why can I not load this this really doesn't let me load these now like this seems pretty annoying I'm gonna try and open a jar file this is why I never update things because I hate when things just stop doing their basic functionality that I make use of SafeMode I don't want to know SafeMode I'm gonna reinstall I don't even think open oh you know what you can do though actually control o why is the layout not at the top of this if I modified we just modified it 26 that's then you get in here and it knows that it was modified 6 minutes ago doesn't make a lot of sense what is this nonsense and where's the CSS and why can we not just open the file like normal why does it have to be this way Mozilla I like your browser but let's not with this what are we doing um yeah we're just not gonna use Firefox I guess because it doesn't work anymore for that for some reason I guess I don't know is that too hard I don't know feels feels like a good workflow it used to work in Firefox don't really see much of a reason to change it yeah we did totally not add it to the docs page so I'm glad we checked this is not the right place to change it though it's here I'll put it with the layouts we have good layout actually I did not add page layout either whoops may add page layout while we're here I don't know why these ones all have more stuff too what is I don't know what this does but we probably want this for this one open developers console whoops I'll put this back in a minute didn't actually print anything I'm actually showing anything in here either I think I've run into this before actually this this part feels very familiar I think even the old version of Firefox anything that was file colon it did not treat as network which technically it's not going across the network so I can see why they would do that but also it would be super useful as a developer if it behave the same as network even though it's on a local file so yeah I don't know if you have anything more specific inside the developer console to look at I'm happy to pull it up but I didn't see anything that seems super helpful in there fortunately did I not save it oh I didn't regenerate it actually did save it but I didn't regenerate it or it has no display that's all I mean board doesn't have display on every device because the CSS file location is relative to the document route rather than the current file that could certainly be the reason for why when I did it like this it got in resents not really maybe but not really any easier to find that CSS thing you just said that's I would assume that's probably part of the reason if not the full reason for why when I did it this way it loaded without CSS I it doesn't even have a fail in here though I mean this is already like this is not where it's at so like it already is doing something to move my file to here or to make a fake copy of the file that's a link or some kind of magic it's already not just like showing my file that I told it to open which is frankly a little frustrating if I'm honest but I don't really see the need for them to like change it to be in a different location than it really is especially when I just told it to open it right this didn't succeed I guess we mock board I don't know I don't know what we do here I don't want to take away the default because I do I mean maybe we say none maybe we say none and then we set it but I think it's gonna still fail do we use board for anything else no oh maybe no maybe we do like might as well not import it if we're not going to use it either this will be mad because imports out of order blah blah something that's fine we have a specific reason for doing this we can because if if they pass a display then we don't need to use this we're not going to use it for anything so we might as well not import it again I think just like it's pilot will disagree I'm sure but too many branches is it gonna complain about the line length are you missing mock board yeah I think that's what we're gonna have to do is mock board have console will show file loading issues yeah I did I'm pretty sure I did refresh after I had it like network tab refresh it doesn't even show a CSS request but like the page definitely does make a CSS request all of these here kind of making their browser harder to use for development which I kind of don't like very much they also don't care probably too much about my opinion so that's cool um so we did pass but we still fail here though it is a different reason than board was this optional requires a single type union nice okay alright there's page layout which I didn't create right now but I did create before and forgot to add to the docs and here's tab layout nice okay uh so now one more time are we still passing pre-commit and we push uh oh and we somehow we got away with not mocking board actually as well so that's weird I guess moving it out of the uh argument maybe make it so it doesn't care or put wrapping it in has adder I guess so it knows that it will have board or I mean display rather not sure why it's uh not sure why I was able to figure it out but works for me um I don't know we did so many things working on tab layout and simple test example so I'll make a PR from this uh and then I think I'm probably heading out here pretty quick after that it's been about two hours I will be back in the morning um I got some grocery shopping to go and do tonight so let me catch up on the chat I've had this scrolled for a while I have an idea to define three labels uh on a certain tab layout page multiple labels on one page uh need to add it to auto doc maybe firefox is on a downward as far as I'm concerned yeah updating this is what got me I updated it the other day but it update I updated it cause it made me frustrated cause it wouldn't let me log into Gmail even though I was already logged into a Gmail account so I could like go to Gmail be logged in see my emails do all my stuff I try to log into a different account and it was like you can't log into an account with this browser you need to use a supported browser and then it has a bullet point list of supported browsers and firefox is on there and without a version number but apparently mine was too old and apparently you can't log into Gmail with whatever version I had before anymore so I updated it with clenched teeth like you said and uh it was alright for a few days but I am starting to notice more things as the days go on where it's like it does different stuff that I don't like but life sometimes one of the pre-commit errors is import should yeah yeah a pilot error is what that is pre-commit is what we use to run all of our things together with one command but pilot is the thing that actually complains about the code I'm not gonna say code format but the way you write your code pilot complains about it in this case because I put my import outside also I'm still catching up you probably said this even before uh I fixed it but feeling somewhat lint exonerated now yeah lint I mean it's it's frustrating sometimes right it's like it helps you write nicer code yes I grant but there are times where it flags on stuff that accidentally encourage you to write code that's actually less readable in my opinion but it's a very opinionated thing right like whoever made pilot has the opinion that this leads to the most readable code and like they probably know a lot more about it than I do too so like their opinion is certainly just as if not more valid than mine but it you know it does sometimes point you towards stuff that I don't necessarily agree with I guess it doesn't care about types inside the functions and you mean for not having the mock here else maybe um let's see I will go back to Firefox for github though see here many windows nope that's the dev here we go and I'll make a PR we'll uh we'll wait on the actions to pass in github as well if there's any reason why the actions don't pass in github I'll take a minute to try to fix it but otherwise I think I'll head out after that and then um if folks are interested I'll be back around tomorrow morning so deep dive is fridays at 2pm pacific uh 4pm central us time which is the time zone I'm in boom right there 2pm pacific uh that's deep dive and so you'll you can catch me at the same time every week on fridays um until eventually I guess Scott will come back I don't know for sure when he when or if he's gonna take back over deep dive but eventually he may be back in the slot um Saturday mornings at 10am central time which again is my time zone so I know I jump around and say different stuff in different time zones uh the reason I do pacific for deep dive is just because that's where Scott's at and that's what it was always announced as before with 2pm pacific so I didn't want to like change it up too much um but saturday mornings 10am central time uh so you can look up whatever time zone you're in and compare it to us central time then uh at 10am on saturdays that's when I also stream similar types of content so if you like this sort of stuff and you want to see more that is when you can uh follow along to get more and I'll always post the links when I get started over in the live broadcast chat which is uh the discord chat that's right down below us right here um down below me not really I guess me and my little cyclops person but yeah for sure thank you thanks for hanging out I read a blog article from one pilot maintainer and won't say anything about it because I want to remain polite and in accordance with the code of conduct yeah yeah that's tough black is the same way too like not no compromise code format and then like sometimes people don't don't like it but it's kind of like a race whoever whoever builds the automated tool that's the easiest to use and the easiest to add to see I kind of gets a lot of ability to define what is and isn't correct or you know most readable or whatever like they built the tool that everyone uses therefore they kind of have control over what everyone considers good or correct in that way uh let's see I think I'll mark it as draft for now because I will actually go back and add the touch example as well um which is not that different but is a little bit so I'll add that as a separate one but I'm not going to do it right now so what I'll do is uh make this one a draft well it's still run the actions for a draft I think it will right um also changed what was it page content list or something page content list inside of page layout yeah page content list code page content list inside page layout uh to be public no leading underscore because it's reasonable for code outside of it to make use of that attribute which the tab layout does um yeah we could probably oh no we do need those right because those are used for the types yeah uh we'll put also noticed page layout wasn't in the docs also noticed page layout wasn't included in api to rc for the docs I added that as well do anything else oh ah I want to I do want to actually rename this I'm going to make one more push I did I meant to do this before actually I want this to be simple test not test that should not cause anything to start failing I don't think but it also costs nothing to just run it and see okay pushing okay this will update I think you can refresh this and not lose your stuff but I'm a little paranoid so I'm going to copy it first and then refresh okay yeah we kept it and I'm just going to double check yeah simple test okay create draft hopefully this is going to run the action still yes okay so I'll wait on this to pass actions if anybody has any last questions or comments or anything now is the time because I'm going to head out once this finishes yo what's this live about just got this recommendation from my stream first of all welcome thanks for thanks for tuning in arming over there in the youtube chat I am about to head out so it is going to be ending here pretty quick but the thing we're working on is all stuff related to circuit python you can learn more at circuit python.org also if you want to catch the VOD at the beginning of this video I explain a little bit about what it is but I can also give you another quick high level while we're waiting on that thing to run in the background basically we're writing python code that runs on these tiny computers such as this one right here which is a a pie portal this one has a nice I'll say relatively big touchscreen obviously it's a small touchscreen compared to like a phone or something but it's pretty big for a microcontroller this one has a color screen on it with a touch like in the version of the code that supports touch which is not this one we can actually touch on these tabs that's actually what we implemented during this stream so if you do go back and watch the VOD that's what you'll see me work on generally speaking though the stream is just about circuit python related stuff sometimes we do development of libraries like I was doing today on this tab layout widget sometimes we do development inside the core sometimes we do development inside like meta projects that go alongside of everything like circuit python.org this is a website sometimes we do development on that just the central theme that brings everything together is that we're always working on stuff related to circuit python on the stream so yeah let me know if you have other questions I can answer while I'm here but that's pretty much the kind of like 50,000 foot overview is we're writing python code that runs on these tiny computers and you can see there's all different shapes and sizes and stuff this pi portal one with the display that's the one I have over here but obviously there's lots of different shapes and sizes and form factors of these things depending on like what you want to do with it that's how you kind of choose which one you might want to use for a particular project at least black doesn't enforce two space indentions yeah that would be rough I do I am like I'm pretty laid back about format there's not a lot of format that bothers me but two space indentions do actually kind of bother me because they're so small I can't I can't just scan and tell which one's two and which one's four and stuff so thanks a lot Tim and all others online thanks for the tips, hits, etc. yeah for sure thank you again for sharing your work and doing your work and being interested to work on stuff that I'm doing you're amazing to me so thank you as well and I would say like please feel free like after this one gets merged or even if you want to do it before that's fine as well feel free though to make a PR and add your own example if you would like or if you want to refactor it to use the touch function that I add or you want to keep it how it is that's fine as well but feel free to add it like an advanced example if you want I think that would be a cool thing to have in this repo interesting is this says all checks have passed but this says X so do we think that's just a visual bug oh it says green up here too do we think that's a visual bug here or do we think we actually failed and it's a visual bug here right we don't have like twitch points bet on it right okay so who thinks you want to do a fun game who thinks that it actually passed or who thinks that it actually failed you can put in the chat and then I'll refresh after a minute I would quit using spaces if anybody wants to guess if not that's fine too I think what do I think I'll let's see I think it I mean we ran it locally so it should have passed right I think it passed that's my guess I'll give you like five more seconds because I think we're on a delay a little bit so give you a few more seconds if anybody does want to guess it's totally cool if nobody does either I also can't see the twitch chat so if there's chatting I apologize but I'm not seeing the twitch chat YouTube and discord are the places to go let's refresh it yeah okay visual bug here that's interesting I've never seen it do that before where it put a red X there even though it was gonna pass I mean even though it did pass double check here yeah huh see something new every day alright so yeah I'm gonna I'm gonna head out for now I will I'll come and add a new commit to this PR probably tomorrow during the stream I think I'll work on that at least for a little bit I'll add the touch one and then as soon as everything is good to go I'll switch this over to to non draft and then you know I'd be super stoked if anybody wants to leave a review on it and then eventually we will get emerged in and everybody will be able to start using the tab layout so alright wrapping it up thank you to everybody who watched and interacted chatted along in the discord with us here thank you again also to paulsk I know I've said it a bunch of times but thank you again to paulsk for working on this stuff and sharing examples near doc is always helping out everybody in the discord myself included thank you to you to grover james biata arming if you're still around new new viewer thanks for tuning in 40 g uh also we have I say see grover remember for sure linux 203 thank you games dexter yeah thanks to everybody who watched Dave Odessa I think took off a while ago thank you to him as well and again I'll be back tomorrow morning and yeah thanks I hope everybody has a good night and I'll I'll catch you all next time