A Tour of Iced 0.10

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
we talk about web-based UI tools on this channel quite a bit but rust can also power native desktop UI as proven by the iced project ice 0.10 is a big update for iced but I'll be assuming you don't know what iced is in this video and instead focus on an overview of the project as it stands landing on the ice website there are two places that you can start the guide or the API reference the API reference is the docs.rs page while the guide is um incomplete however the guide does point us to a number of important places back to the API reference on docs.rs the official examples which live in the GitHub repo and is very common practice for rust projects and awesome iced an awesome list for iced projects that is officially maintained first and foremost iced is a desktop based application framework they do say cross-platform GUI Library here because it can compile to wasm and run on the web however the major use case I see for Native capable wgpu-based applications is running on the desktop it claims to be inspired by Elm which makes a lot of sense if you look at the docs.rs they continue to say that iced is focused on graphical user interfaces so it's not really a 2E based or terminal based framework that you can use and is strongly focused on Simplicity and type safety which very much matches the elm idiom overall the features list out that it's a GUI framework it's got Widgets or components it's got cross-platform support and responsive layout you can create your own widgets and it's typesafe for me the only huge call out in the docks right here is the modular ecosystem and right away they make it clear that iced is meant to be used by two different types of users end users building applications themselves and GUI toolkit developers or ecosystem contributors these are people that would be building widgets for other people to use or integrating ice inside of say the baby game engine or something like that we'll be talking about the native side of things today so you can roughly split that into renderers and shells that is something like win it to manage windows and something like wgpu to render Graphics there's a software-based renderer that's called out in the readme that isn't in this document that we just looked at above detail the ecosystem that's because the software-based render is fairly new and it can be used as a fallback it's worth pointing out that when it is the window management library that is also used by projects like Bevy so it is a widely used rust ecosystem dependency as is wgpu which is not only used in Firefox to power web GPU for the web but also inside of Bevy and other projects so let's get around to looking at what elm-like means or what it looks like to write a very simple counter there are four call outs in the docs State messages view logic and update logic each of these is sort of cordoned off into its own world so let's start with state state is just regular structs in this case we have a counter struct that has a value that is an i-32 and I'm going to scroll down a little bit further than you might expect to take a look at the view because I think how you declare views and how you declare your application in the way it looks is fairly important so we imple counter and provide a function called view this takes a mutable reference to self that is the counter and returns a column message we have these macros that can do layout in either a column direction or a row Direction and inside of those macros which looks somewhat like a raise we have more components or more widgets whatever you want to call them in this case we've got a button we've got some text which has the value of the counter so self.value and another button there's event handlers on each of the buttons for both for incrementing and decrementing and we can set attributes like the size of the text these are all built-in widgets that come from iced widget and even if you're not super familiar with iced this should seem fairly straightforward we've got what is basically a vector an array of a couple elements laid out in a certain way that have certain attributes you'll notice that when we on press we send messages so in this case we've got message increment pressed and decrement pressed this is a regular rust enum so we've got a regular rust struck for state and a regular rest enum for messages these messages carry data that we then need to update our state or application with which we can then re-render in this case we aren't carrying much data just whether we should increment or decrement so we do need this update function as well to be able to actually respond to these messages so when a message comes in we have a mutable reference to self in this case counter which is effectively our application type at this point and the message that came in if you've used fold or reduced before or worked with something like Redux this should look fairly familiar we match on the message and we do something to the state and then it's updated so basically we have this application that has some view Logic for displaying things like buttons that the user can interact with that updates Itself by passing messages to this update function which then modifies the state and so on and so forth that brings us to the tour I've chose the tour because the tour is roughly 700 lines of code if I remember correctly yeah 700 Edge lines but it doesn't contain any unique logic I don't need to explain anything out of the ordinary if you're familiar with rust it's important to note that this tour is the tour from inside of the iced repo and that other than iced it only has one dependency and vlogger I would probably use tracing personally but you know use what you want and today we're going with whatever the example wants as far as features go we're using the image feature in the develop feature this is because we intend to render images and also because the tour will show us some of the debug tooling we've got a ferris.png image and index.html that we aren't going to touch although it uses trunk if you're familiar with wasm builds and rust and then we've got our application so we start off with this page that says welcome some paragraphs and then a next button so the way that this works is you can click these buttons go next and back so there have to be some kind of event handler there has to be some way of us getting from one page to another this kind of shows one complete set of UI and then switches to another complete set of UI so let's take a look at how we get started here as usual we'll start at the main function the main function returns iced result which is a very common idiom in Rust then we initialize the logger and we Set tor run so Tor run takes us settings default and we can see that we've defined tours of regular struct here with two Fields it's got debug which is true or false and steps which is a steps which we'll see later the tldr first steps is that it's just a list of each of these pages so we start out and we Implement sandbox for tour sandbox is one of two traits that you can Implement to get your application started on the right here we have sandbox and on the left here you can see application the big difference between these is that application lets you do async stuff and sandbox doesn't so the general recommendation of the iced project is to start with sandbox and to upgrade to an application if you need to upgrading shouldn't be too hard so we can see a couple of the functions that we defined earlier new title update and view as well as the Run function that we actually use to start our application and the settings type that contains the number of settings for our overall application this includes settings like the default font and the default font size which in native land can't be taken for granted on the web we're very used to just having a default font size and default fonts and being able to load things all over the place but don't take for granted the fact that fonts work here so we choose to use sandbox which means we're not going to do any async stuff and we Define our message type to be message if we look for enum message which is where our message will be defined we have back press to net text pressed which are these two buttons here as well as step message step message is significantly more complicated and contains the logic for various different toggles when we're on each page so we've got our message type we've got the new function which returns a new tour with default values we've got the title which gives us the title so up here it says welcome Dash iced and then we've got our update which takes the message and does things to the state as well as our view which defines what we should show update won't make too much sense we're just matching on the message and for back pressed we go back which is a function we Define later on steps for next press we advance which is also a function that we Define on steps and for step message then we update each of our steps our view function controls how we lay out this each of these pages right so if we click next then a back button shows up for example and this is controlled by if steps has previous the most sort of interesting thing about this to me is that this is regular rust it's an if expression we call a function we get a Boolean back and then we've got this is row Macro for laying things out in a row and if we have a previous which is a function we Define again this is on steps here and the has previous function is just checking for an index of greater than zero so if we have an index greater than zero push a control into the controls vect basically in this case it's a button that sends a message on press and is styled as a theme button secondary button you can do dark themes and light themes and all sorts of things which we probably won't really get into today horizontal space features fairly prominently so we control push this back button and then some amount of space in the middle here that just fills up the area and if there's a next then we want to also show the next button can continue is a little bit more complicated though because can continue is not just a function but also a field on each of these steps so there will be conditions that determine whether we can continue or not so that function is just a little bit more complicated but it's only accessing the state of Step each time we use view we use self.debug to determine whether or we should show debug or not we'll see why that is later and then we set up a row for the content on top of each of the buttons in this case we're setting Max width and spacing and padding and whatnot and although it's not mentioned here or anywhere in the tour at all you can also do some responsive work so overall that's pretty much it each of these steps is something that we can also render out so we've got step welcome and slider and whatnot we're in slider right now so the slider starts with a value of 50 and of course steps also implements and uses update and View and things like that the way these are implemented is by looking for a particular step in the VEC and then calling the update function on that step step then is an enum for each of the sort of pages that we have we Define a step message which is the message that we're using for each page as well as the update function once again so you can see this starting to get pretty repetitive to find the view to find the update to find the message our view function is a little interesting it's not super interesting basically we call a function on step for every single page and this is where I kind of get a little bit nervous seeing this I would love to see this broken out a little bit more because even though they describe it as being useful for simple applications right now I'm not sure that this setup would grow beyond that so each of these functions is a regular function that we also Define on step so container for example is just a column with some text and some spacing so on the welcome page if we go back we can use self-container welcome which passes the title in here and renders it at a size of 50 inserts some spacing and then pushes a bunch of text in over and over then once we're on the slider page we get a value from our state as well as the step message type because we passed that into everything that we are rendering which allows us to create this slider from 0 to 100 which is a native widget pass in the value we want it to be at and use the step message slider changed message which takes a u8 so there's a little bit of shorthand going on here because step message slider change takes a u8 but we're not actually passing in a function that we then construct slider changed with here other than that it's more of the same over and over and over if we go to the next page rows and columns this will change the layout for these two buttons between a row and a column and all this is is a match on the layout state for this particular step again use a built-in radio button we trigger and respond to the layout changed and we do that by matching on the layout value which either gives us the row macro or the column macro text can change sizes but we already knew that and it can change colors as well slight increment over what we just saw this is where it gets a little bit more interesting for me personally this is the radio button step or the radio button example inside of the tour and it's where we get to use iterators so language is our iterator here and we've defined a function on all that will give us all of them so there's six of them total CL Ruby Etc clone the values map over them create a radio button for each of the values and we create an element from each of those so to render a selection of radio buttons we get to iterate over some list and just create elements however we want to this I really like I really like leaning on Rust for iteration because iterators and rust are a really well trodden territory and I love that they didn't go with something that was a little bit more custom here so if we click the right button we get the next button and if we click the wrong button so say Haskell because ice is not written in Haskell it's written in Rust then the next button disappears and this is the language selected step message so if we look at the language selected then our language comes in because we use radio buttons and if we look at the update function when a language selected comes in with a language the selection gets set to some language and this selection is coming in basically as a prop to our component it may not be obvious at first why the next button is capable of showing up but remember we call that can continue function which we then call the steps can continue function on earlier when we're trying to render the next button and if we're in the radio step we get that selection and check to see if it's some language rust so the logic here is kind of spread out a little bit which I don't love the thing that triggers whether the next button should show up or not doesn't live where the next button shows up or not it lives kind of somewhere else but this continues over and over so we've got a toggle button here we've got an image here that can be resized all of these work exactly the same way we've got a scrollable area here so this is about halfway and then we scroll all the way down and we see Ferris again we hit next and then we get to inputs inputs allow us to type inside of but one thing that is notably missing is I can't hit tab here and get through each of the text inputs we can set password mode we can show an icon at the end and this is all implemented in the same way that we just saw so there's nothing special about this we just call the function for the component we call more functions on the structs that are returned we set the paddings we set the sizes we use regular if Expressions to determine if something should be shown or not and we just kind of push these stacks of components together either in rows or in columns or whatever the final most interesting thing that I've seen here is the debugger and this is why we're passing debug in through our entire application here if we click explain layout we just get a free bounding box on everything that we've laid out which is so nice on the web I'm used to just like setting every div to have a red border kind of thing you know or setting everything to have a red border but having a button that does this explicitly is really nice because you can kind of see the space between this checkbox and the explain layout and you can see the wrapping containers around all of these elements and where they're positioned and how much padding or margin they have that kind of thing and of course if you leave it on you can go back through this entire thing and see how everything is laid out and where all of these elements go but that's it for ice today I hope you enjoyed this practical tour of iced there are a lot of GUI libraries in Rust more than you might think so if you've got a favorite that you want me to check out leave it in the comments and let me know what you think of heist have a great rest of your day
Info
Channel: chris biscardi
Views: 22,359
Rating: undefined out of 5
Keywords: rustlang, desktop, gui, wgpu, webgpu
Id: XrR4VCKB0cQ
Channel Id: undefined
Length: 14min 45sec (885 seconds)
Published: Mon Aug 07 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.