Cross Platform Graphical User Interfaces in C++

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello as regular viewers of the channel will know I really like C++ and I use it for pretty much everything but there's one thing I've not yet covered on the channel and that's using C++ with graphical user interfaces or gooeys for short C++ and gooeys have a bit of a notorious reputation for some it's akin to vigorously applying a cheese grater to one's buttocks and for others it's like removing teeth with a chainsaw for some reason C++ and gooeys have just never really married together very well in this video I'm going to introduce the WX widgets framework which is quite a mature and sophisticated graphical user interface API that we can use to create graphical applications in C++ now I don't want to start some sort of internet flame war and I'm well aware that there are plenty of other frameworks for doing graphical user interfaces in C++ but I'm choosing wxwidgets because I've been using it for 15 years it's mature and stable and very customizable though we won't go into the advanced customizations in this video in fact I'm really only going to scratch the surface of what we can do with C++ and gooeys because getting the framework set up in the first place is often the largest hurdle to overcome so let's get started in fact let's start at the very beginning most of you will probably be quite familiar with graphical user interfaces and some will argue that we've actually covered them all the time on the channel after all we show things on a screen and we interact with them but what I'm specifically talking about are those things that you frequently see in your operating system I don't mean things like console game engine or pixel game engine I mean native applications such as this example one here where you've got list boxes and text entry boxes and buttons to choose from buttons to press and indeed a window you can move around close maximize minimize and resize so I don't have to keep saying graphical user interfaces because a bit of a mouthful you'll often hear me say GUI gee you I now specific to Windows and C++ you've had some options for quite some time but more recently it's become quite difficult to find a good combination of GUI development for a C++ environment you've always got the windows API but this is a bit of a mess fool to use it's quite deprecated and programs in an old style of C++ in fact some may argue it's not C++ at all three million years ago windows also introduced the Microsoft foundation classes which attempted to apply an object-oriented approach to graphical user interface development again the remnants of this still exist but on the whole it's quite difficult to get up and running and use now as the nature of Microsoft and the structure of Windows has matured they now rust upon us the idea of universal Windows platform which is a complex framework of components to make your applications look modern and polished and also be entirely compatible with the product range on the whole it's my belief that Microsoft have strayed away from allowing people to do C++ and graphical user interfaces and have instead decided that people should try new c-sharp I should say at this point that that's not the daftest of ideas c-sharp is really engineered towards producing graphical user interfaces using the WinForms framework and it's actually quite a pleasant and rapid development approach but I'm well aware there were just some of us that loved C++ too much that that's the language we're going to stick with now I'm quite certain that all this mention of Windows and Microsoft has already caused half of you to stop watching but what do you do if you also want to have a user interface in Linux what are the options available to you well Linux being Linux I'm quite sure there are at least 20 million different options admittedly it's been some time since I've had some familiarity with Linux but I remember that gtk was always a popular graphical user interface development framework because of course with Linux you can switch the frameworks at will and the reason I bring Linux up is that there is no commonality between any of these technologies and any of these technologies so in the past the programmer would have to create a completely unique application for a Windows platform and a completely unique application for a Linux platform and possibly Mac and other platforms too which is quite frustrating obviously as a programmer we want to do it once and have it work on all of the platforms and there have been options for us to do this so if we wanted to do a GUI application that works on Windows and Linux before your options typically could involve something like Java and Java runs in a virtual machine so it's guaranteed to look and feel the same way on all of the different platforms and I recently had a look into Java and that's become a complete mess and so wanting to stick with C++ and I know there are many frameworks out there but the big two are certainly QT + WX widgets these two technologies are more than just GUI frameworks their entire operating system platform frameworks so they'll contain components to handle multi-threading across different systems to handle file systems to handle things like peripheral input as well as just the look and feel of your applications and both of these technologies do something quite cool they use the native available components for those systems and so if I write my application and use the WX widgets framework it in fact uses Windows controls on Windows systems and Linux or gtk controls on Linux systems and whatever the equivalent is on Mac I've never used a Mac and this means that your application doesn't look out of place when it's run by the user on those systems it's not 100% perfect but it's not bad and I know the choice of framework is quite divisive amongst the community but today I'm going to look at the one I enjoy the most WX widgets which will allow me to make a single application source that will provide a graphical user interface on different operating systems I think before we get stuck into any code it's important to understand the general structure of how a graphical user interface works in all of my videos to date I've taken the traditional program model where we have a while loop and fundamentally in that loop we get the input from the user we do some stuff and then we update what the display displays and this approach is called poling where every iteration of the loop we sample some input to see if anything has changed State and if anything has changed State then we act upon it by doing the appropriate stuff and we may alter the things that we want to display now from a computer systems perspective all applications follow this model but when working with gooeys the process is abstracted away it's hidden from the end-user so the programmer works with a different model the GUI can be broken down into two major components the structure and events the structure defines what the GUI looks like fundamentally a GUI consists of lots of little rectangles so here we've got the window itself which is a rectangle and here we've got the buttons and here we've got a list box and here we've got a text box and here we've got radio buttons put in fact they're actually surrounded by little rectangles and all of these little rectangles unsurprisingly are called windows or panels depending on the approach that you're coming from and indeed the operating system and its libraries are tasked with supporting the upkeep of all of these windows and so a GUI can be represented as a tree like structure we have our main form in the background now form is one name yeah you may hear me call it a dialogue you may hear me call it a frame sometimes just a window but it represents the overall bounding rectangle that is our application and that form can act as the parent for lots of sub-windows so we may have text boxes or buttons and we can have more complicated structures such as a list box which has the scrollbar at the side now that scrollbar itself could be a window and the content of that list box could themselves be text boxes this means we can construct a tree using a parent-child relationship so windows have parents that are windows and a parent can have many child windows events represent things that have happened in time for example when the user clicks this OK button a whole sequence of events may have took place but one of them in particular will want to call some function that we provide to suggest that the button has been clicked so on button clicked now I'm deliberately simplifying things here because as I mentioned there's actually quite a lot of events that have taken place I've drawn in here the mouse cursor as the mouse was moved over the button we actually got a on mouse entry event whilst the mouse is moving across the button we're getting on mouse moving events as the user presses the left button to start the click we may get something like on mouse button down when the click has finished ie the users lifted his finger off the button we go I get the opposite on mouse button up and as the mouse exits from the buttons rectangular area we may get something like on Mouse leave so fundamentally there are lots and lots of events happening across our application all the time and we as programmers don't want to have to deal with every single one sometimes it's useful to pick one out and work with it but working with all of these all of the time is very frustrating so a good GUI framework will be able to look at all of these events and work out what sequence of actions and timing has occurred to generate a more general event which is useful to us the fact that the button has been clicked and therefore when we're developing gooeys after we've declared what the structure of the GUI should look like we then populate some code with what are called event handlers and these are specific to the functionality we want to provide in our application but and this is quite important fundamentally we're getting away from this idea of sitting in a while loop instead what we're doing is providing little nuggets of code which can be called at any time in any order quite unpredictably and so this is quite a shift of thinking for the programmer as I've already mentioned the framework I'm going to use is WX widgets and you can get it from wxwidgets org I'm not going to argue whether it's better or worse than other frameworks I'm just going to show in this video how we can set this framework up and start using it to generate some applications it's very mature and actively developed by strong community and to get it just go to the webpage wxwidgets dot org and click the download now button this will take you to the downloads page now there are some other languages that WX widget supports but we're interested in the C++ version which is its major version and I'm going to download the source code because I'm going to compile it myself and install the SDK that way and I'll get it by clicking the Windows zip download link here and it's about 30 megabytes just before I move away from the browser widgets also comes with an extensive amount of documentation and many many components so here is a complete class list let me just zoom in slightly so you can see some of these their complete class list of every type of component that wxwidgets provides there are hundreds of them so let's just pick a basic one something which you'll use a lot which is button there it is so button is the thing that you click in order to do something and the documentation is very nice so they've got her an inheritance diagram to show where it lives within the framework and if you're not completely familiar with object-oriented programming don't worry too much typically the methods are exposed that you need and the way that you interact with these objects is quite intuitive but it does go on to give you quite a detailed description of how to use the component and all of its parameters oh very nice it also shows how the button will look on the different platform so here we've got the windows experience here we've got a gtk on linux experience and here we've got a Mac experience and that's because 3x which has used fundamentally the native components for that operating system ie unlike Java it isn't drawing the buttons in a particular way there's also a lot of examples on how to use WX widgets as part of their documentation package and as I said before it's not just a graphical user interface framework it can handle all sorts of things for the operating system - it even has links for Open GL applications using the ribbon parts of the user interface and printing stuff for those that still print things now that the download is finished I'm going to go to my SDKs folder on my hard drive which is where I install all these sort of things and create a folder for it and it was wxwidgets version three one two and as you can see I've got several previous versions of dual UX widgets for other applications I've been developing the zip file we downloaded contains quite a lot of stuff I'm just going to grab all of that from the zip file and copy it into my new folder you right that took far too long but there's a lot of files for it to copy over now I said we were going to build the UX widgets from sauce and the wxwidgets developers have made this very easy to go to the build folder go to MSW Microsoft Windows and here you've got lots of different Visual Studio solutions for all the different versions of Visual Studio the most recent one that they're supporting in this download is Visual Studio 15 I'm currently running 17 but that shouldn't be a problem it will pop up a little warning and because now Visual Studio is concerned with security it you don't want to just be compiling any old code that you're not familiar with and running with it of course so I'm going to say it's okay to open this I trust the provider of this library in the solution Explorer at the side we've got all of the major components of wx-- widgets and this is very important don't do anything other than this at this point go to build select batch build and it will list all of the different build configurations that this project provides now w.x widgets is quite unique in the fact that it'll allow you to build things in a DLL fashion or a static library fashion if you're just starting out with graphical user interface programming don't worry about it all I want you to do is select all and then click build but before you click build and this is really important go and make yourself a cup of coffee as depending on the capabilities of your computer this can take up to 20 minutes don't worry too much if you see any warnings or errors there are actually very few and if everything goes to plan you won't see anything at all but just let it do its thing and drink your coffee whenever I'm compiling something massive like this it always makes me feel a little bit of sympathy towards those that work on projects that contain thousands of files compiled times become a real issue as casual hobbyist coders which I believe most of the viewers of this channel are but we take it for granted that we can just click compile them within under two or three seconds our application is already up and running but this is the reality for programmers all over the world is that they need to really sophisticatedly know compile their code and configure their build environments in such a ways to make this job less laborious and that's in itself can be quite a challenging task actually on the next you wouldn't do it this way depending on the vendor of your Linux distribution there a variety of different ways to install it and the wxwidgets website actually provides good instructions on how to do this but the one thing I will say if you do downloading for Linux and you're compiling from sources and you will still need to sit through it compiling but it does actually happen a little bit quicker than it does on Windows [Music] [Applause] [Music] things they sit through for this general and so after a nice cup of coffee we should see that all of the projects have succeeded and that none of them have failed if however you have experienced any that have failed for whatever reason a good way to overcome that is to just go to build and batch build again don't click clean or anything just click build it's typically because something was built out of order or there was a problem with one of the tools and some dependencies got messed up so just click build again and you should be okay once that's built closed down visual studio you're done you have built the SDK from source and what will what it will have done is have populated the Lib folder from our original SDK installation directory so now we've got DLL versions and static library versions of everything that wxwidgets needs before we can start developing we've got one last step we need to do and that's is we want to add an environment variable for WX widgets so I'm just going to go and edit that now so we'll go to the system's environment variables click the environment variable button and I want to add a new system variable and I'm going to call it WX win and the value is just going to be the path to the folder where we've installed it so e drive SDKs WX three one two that's just to make life a little bit easier in Visual Studio okay click OK and we're done now in a freshly opened Visual Studio I'm going to go to file new and select project and most of you expecting me to go we click on Windows can't know we don't you see now this different this time we go to Windows desktop application and that's quite an important distinction because we're making an program which is going to have to be very compliant with the operating system our program will merely be a guest in the operating system far more so than it has been in previous videos and I'm going to call mine a video WX widgets and click OK now as is normal with Visual Studio we'll go ahead and create something for you already and this is actually the win appiy way of creating a graphical user interface and the code or already looks quite messy in fact the code that it provides we can compile it and run it simply creates a window with an about box but it's looking at this is where we can see that there is a bit of a reputation with C++ and gooeys so this isn't using WX widgets this is using the native windows way of doing things and it's a mess so what I'm going to do is delete all of the files associated with this project now I know some of you in the comments will say well you could have created an empty project in the first place well I'm just doing it this way and they select delete and remove all of those don't want any of them bye-bye and what I'm going to do now is set up my build environment to use WX widgets firstly I'm going to add a class and I'm going to call this class C app now I'm going to right click on the project and go into the properties and I want to make sure that I'm setting the properties for all configurations firstly for C++ I'm going to disable the use of precompiled headers I don't use them although ironically that would reduce the build time for really large projects that I was alluding to earlier we need to tell the compiler where to look for certain files so in the general tab under the C++ settings I need to tell it where it can find the header files now this is made easier because we created an environment variable WX win which is pointing to the base directory of the folder slash include there's actually two locations I need to add the second one is also in a similar place WX win slash include /m SVC and that's what's making it specific for compiling with the Microsoft library of tools then I want to go to the linker options and tell it where to look for the libraries themselves now today I'm just going to use the static library configuration of WX widgets I don't want this video to be a discussion between the virtues of static libraries versus dynamic libraries and again using our environment variable WX win / Lib / vc lib click apply now that's applied to both debug and release configurations assuming we're running a 32-bits application at last we're now ready to start coding a wxwidgets application one thing you might have noticed already is we don't have an int main and this is what I was trying to indicate at the start so you have to think a little bit differently the framework itself is going to mask the int main and the fundamental program loop for us our entry point as a programmer is really just a starting class that represents what our application is in many ways this is not dissimilar to the pixel game engine well firstly let's include WX widgets and I want to inherit from a base class provided by the framework WX app our application class needs to implement one function which is on in it so let's give that some implementation and we'll just get it to return true for now even though we've been heritage from the base class WX app we still need to tell the application where the entry point of our program is for example if I click to compile it now we see unresolved external symbol win main now win main is like int main for a regular C++ app but it's specific to being an operating system compliant application so we need to go and tell WX widgets to go and generate main for us and we do that by using this macro WX implement app in one of our CPP files the most convenient place is the application file of course our app class isn't actually going to show anything it's just really to get us started and get us up and running with a graphical user interface so I'm going to add another class main again I'm going to include WX widgets and this main class is going to be a graphical user interface component it's going to be a form which in WX widgets peak is called a frame we go to the implementation of the main class because we're overriding WX frame we can provide some arguments to its constructor and we'll see there's quite a few to choose from so because this is our base window for application it doesn't have a parent I'm going to specify a null pointer for its parent all windows within the WX widgets framework require an ID but it's not always necessary to actually give a specific you can use WX ID any to say look I don't care just give it something and let's give our window a title one loan coder dot-com dual UX widgets and so that's enough to override the constructor of the frame base class let's just compile and see if everything comes together APIs compiled main is compiled generating some code and success so let's just have a quick recap before we run this we've created one class which is like the launcher for our application and we've created another class which is the start of our graphical user interface so it's here where we're going to define the structure and implementation of our event handlers one last thing to do is to tell our launcher to actually display the window so in my app class I'm going to add a private variable see main frame one I'll have to include main of course and in the on init function of our application I'm going to create a new instance of main and I'm going to show it because main is a window let's take a look and there we go it's compiled and it's produced a little window in this window is resizable and it's got minimize and maximize buttons it behaves just like a window should it's also got the title that we specified one lone coda calm WX widgets and so already even though it's taken a little bit of time to get here the code is far simpler to implement a windowed application like the one we saw the visual studio environments had generated for us automatically now I'm really going to scratch the surface of what we're capable of doing here I'm going to add some very simple components to my form it helps that I have some familiarity with what components are available to me throughout the WX widgets framework so it will be necessary to actually look at some of the documentation before you can dive straight in however you can often make an educated guess about what things will be called before that however and to make the video a little easier to film I want my window to appear in the same place each time so I'm going to tell it to give it a top-left corner of 30 by 30 and to give it a width of well we'll say 800 by 600 for now let's just see if that makes sense yep good so it makes the dialogue just a bit easier for us to see don't forget there is a parent-child relationship between components and Windows so I'm going to add some components now we'll have a button a text box and a list box I'm going to create these in the constructor of my main class firstly for the button we want to tell it the owner which of course is this because the parent of the button is going to be the window not too bothered about the ID again and the next argument is the label that the button will take on so I'm going to have click me and I want my button to appear 10 pixels in by 10 pixels down now those 10 pixels are not relative to the screen they're relative to the top left corner of the window of the parent I'll also give it a size let's have 150 pixels wide by 50 pixels high in a similar way I'll now construct the text box and the list box let's just see what that looks like well I'm not going to win any awards for graphical design but we can see we've got a button with click me we've got a text box where we can enter text and we've got a list box but there's nothing in the list box yet so there's nothing for it to display what I want to achieve is that when we click the click Me button it adds whatever text is in the text box to the list box and to do that we need to handle events we want to be sensitive to when the button has been clicked fundamentally my parent window is responsible for distributing the events and WX widgets provides tools to handle events for us you just need to include them in your class by using this macro declare event table now all events in WX widgets if they're not custom have a type and when you click a button the type is a WX command event ie the do something event so I'm going to create a function called on button clicked which takes an argument WX command event DVT in the implementation of main I'm going to go and create a body for this function however nothing yet associates this button being clicked with this function we need to tell WX widgets to do that binding for us and there's a couple of ways we can do this but I'm going to take the simple way which is again using some macros in the background in the implementation of our class we're going to implement what the event table is so begin event table takes the name of the class that it is producing the events for and it also requires the base class in this event table and we want to be sensitive to a button being pressed so there's a macro called EVT button which is going to take the windows ID of that button I'm going to say it's ten thousand and one for now and Link any buttons with that ID being clicked to the function that we want to call when we created the button we specified that we didn't care about the ID but now we do so let's make sure that they're the same hopefully now when we click the button the system will go ahead and call our on button clicked function and all I want to do is add to our list box the contents of the textbox so I'll interrogate some of the member variables of the listbox fortunately we have one called append string which is going to add a string to the list box and fortunately I can get the string from the textbox getvalue now wxwidgets uses its own string type called WX string and this is actually very analogous to the standard library STD string you can use the two interchangeably once I handled the event I need to tell the system that this event has been handled and we can do that by telling the event that is finished by calling the Skip function let's see what happens so I'm going to add some text to my text box and to click the button click me and we can see hello has appeared in the list box that can repeatedly click and add lots of hellos let's add some of the texts as well and the nice thing about the graphical user interface is it handles all of these corner cases for us we've not had to program the scrolling we've not had to program the selection mechanism or the ordering of the list that's something else clearly something which if we had to code ourselves would take an awfully long time so why did we need to tell the system that we had finished with the event well in this artificial scenario here let's assume i click the ok' button the framework has deduced that the user has clicked with the mouse in a specific location it just happens to be within this ok button for now so the first thing it will do is call the on button clicked function of the ok button but let's say for some reason I didn't care that this button had been clicked I didn't use up the event by calling the Skip function the system then still has an event that needs resolving perhaps the window behind it cares that it has been clicked so in this unusual situation let's say I don't care that the button has been clicked the system will then look at the parent window in that location and if it has one we'll call an on click function and it will do this all the way back up the tree that represents the structure of the GUI until something handles the event or nothing handles the event by calling the Skip function on the event in wxwidgets I've told it that it can skip checking all of the parents the event has been handled it's finished it's done WX widgets has a little quirk regarding use of the new operator typically if we've allocated something with new we should also have a corresponding delete but because of the unpredictable nature of graphical user interfaces WX widgets itself would rather maintain the deletion of objects and in fact down here we can see from the last run of the program there hasn't been any complaints of memory leaks even though I've not explicitly deleted the objects I've created and this is for quite an important but hidden reason as I'm interacting with the application I'm generating many many events these events get added to a queue and a processed in a first-in first-out fashion the events of course contain information relating to certain objects and it could well be that we have deleted some parent object whilst we've still got events that reference child objects in that event queue to stop the application from fatally crashing when it tries to call the function on an object that has been deleted WX widgets will effectively postpone the deletion of the objects until it is sure that it is safe to do so and I'm sure this is just one of the many arguments why C++ and graphical user interfaces just never seem to get along our application is not very dynamic I can resize the window but you can see nothing actually changes regarding the component layout and there's nothing intrinsically wrong with this weave after all specified precisely where everything should be in the window but it's not very adaptable for different display and screen sizes the way that we've implemented this particular dialog is also very rigid it will only ever contain a button a text box and a list box and again there's nothing wrong with that many dialogues exist to serve one particular purpose but what if we wanted everything to be a little bit more dynamic what if we wanted to construct GUI components programmatically depending on the needs of the application for example what if I wanted a 10 by 10 grid of buttons well let's delete what we've got here and we'll do exactly that I'm going to create two variables field width and field height and have a array of pointers to buttons and I will just clean up our event handler and our constructor in the constructor I want to create and populate my array of buttons so I created a new array here which will be 10 by 10 that's 100 buttons I don't want to sit and program all of the code for a hundred buttons I also don't want to personally position them all over the place I want them to be in a grid and I want them to adapt to the size of the parent frame underneath in the previous example we rigidly positioned our button by giving it a top-left coordinate relative to the parent and some dimensions to indicate its size I can do something more advanced I can defer to WX widgets to automatically place the components for me by using what's called a sizer and this is quite a cross-platform concept so lots of other GUI frameworks will also have a similar construct sizes describe the relationship between a parent window and all of its children so for example I could have a sizer which breaks up the parent into nothing but vertical arranged components so every time I add a new button the button will occupy a particular slot in the sizer and as we resize the parent window the sizer gets updated and the sizer updates the size of all of its children I want to position my buttons in a matrix so I'm going to use something called a grid sizer which ensures that all of the columns and rows of the children components are equally spaced so as I add buttons they get added in a matrix like fashion the sizer itself is not a GUI component it's just a structure that describes this relationship so after I've allocated the array for my buttons I'm going to create a grid sizer and tell it how many rows and columns I want I can also indicate the padding inside the rows and columns then with a pair of nested for-loops I'm going to create my buttons and add them to my parent window now in almost every one loan code a video we've always had why time for width + X to turn our 2d coordinate system into a 1d system for the array of buttons so in this instance I'm going to create a new button the parent is still the frame the window it's not the sizer I'm going to give it a unique ID based on its position within the array and my newly created button is going to be also added to a sizer the grid sizer and these parameters are saying please occupy the entire space of the cell in the grid and expand as necessary to follow the constraining dimensions imposed by the grid sizer it's a little bit complicated but once you see it in practice you'll see precisely what I mean once I've constructed my buttons I then need to tell the parent window which size are to use in this case it's the grid sizer and I'm also going to tell it to go and restructure itself depending on the information it's got so it knows now it's got lots of buttons it knows it's got to be 10 rows and 10 columns and it knows the dimensions of its parent so let's take a look and we can see now we've got 10 by 10 buttons on our window and if I change the size of our window all of the buttons change size too you may notice and it might not be that visible on the YouTube video that as I slowly scroll we can see that the window actually extends beyond the 10 by 10 buttons and then they all snap into place and that's because the sizer is constrained to ensure that all of the buttons are exactly the same width and height this means there is only a solution periodically where this is valid this is another example of relying on the framework to just handle the corner cases for us so there we've got a hundred buttons and they're all individually clickable now the eagle-eyed amongst you will have notice down here I've got a memory leak that's not because I've not deleted the buttons or the sizer but I've not deleted the array of the buttons so I'm going to add that to my destructor now I want to handle one of these buttons being pressed and I want to handle them all in a fairly similar way I could go back to my event table and now create a hundred different entries but that seems a little tedious instead what I'm going to do is dynamically associate an event handling function with a button being clicked and we can do that in our nested for-loops so I take the button and I call the bind function which will bind an event handler to this particular event that I've specified as an argument the button being clicked so if the button is clicked please bind that event to this function on button clicked which is what we've got below so I'm binding all of my buttons to the same function in this instance and since I specified a unique ID for all of my buttons I can work out which particular one was clicked and it's x and y-coordinates with some simple maths we like to do games on this channel and since we've got an array of 10 by 10 buttons let's make minesweeper I'm going to assume that you're very familiar with what minesweeper is it's a small game where you click on the buttons and it reveals how many mines are in the surrounding cells and you can use logic and a little bit of luck to deduce which buttons are safe to press and which ones aren't so to store the status of the mines I'm going to create another array of integers which is going to represent whether the mine exists there or not I'm also creating a boolean flag called first click because I want to be sensitive to the first button being pressed that's when I'm going to populate my minefield to give the user a chance or else you know they could click it and immediately it's game over after creating my array of buttons I'm also going to create my array of mines it's going to be the same size of course and in my nested for-loops I'm also going to set the default value for each location in my minefield array I'm going to set it to 0 the only time anything happens is when the user clicks a button on the very first click of the game that's when we want to generate the minefield I'm going to assume that for a 10 by 10 mine field that 30 mines should provide a sufficient challenge I'm now just going to create a loop and randomly generate X&Y locations within that minefield and if there is no mine at that location I'm going to place one so I'll just check that those values don't already exist whether it of mine and I'm also going to check that the randomly selected location is not the same as the location of the button within the array again we don't want the very first button clicked to cause a game over so if this location is valid I'm going to put a mine there I'm going to set it to minus 1 minus 1 indicates the presence of the mine after the first click I'm going to my first click flag to false because we don't want to generate the minefield each and every time before anything else I want to also disable this button from being pressed again we've already tried it now all windows have an enable function and that stops any further user interaction with that particular object the user has click the button they could have hit a mine so we'll check for that by seeing if that particular cell contains a minus one if it does that's game over and I'm going to call from the framework the WX message box function with a message to say well the game is over I then also want to reset the game and resetting the game is quite simple I set my first click flag back to true and I go through all of the mines and buttons and reset them effectively I enable them again and I set the label to blank so the label is the text that appears on the button and I'm going to use that label to indicate to the player how many mines are surrounding the location they've just clicked so if the player clicked and didn't hit a mine we want to go through all of our neighbors and count the number of mines that exist and I do this by having a very small nested for loop here which is just going to iterate around the 8 neighbors of the cell that we've clicked on and if any of those are equal to minus 1 then we keep a count of how many mines surround the cell that has been clicked and if the mine count is not equal to zero there must be some mines so I'm going to use the set label function of our button to display how many mines were in the surrounding cells and that's it not very many lines of code but that's the game play for minesweeper let's check it out here is my matrix of buttons and I'm going to click one of them and it's put a 1 as the label so one of my surrounding cells contains a mine so it's a bit of a guess bit of luck required that's told me that two of my surrounding cells contain a mine so it's a good chance one of these two is a mine let's see how lucky we can get so three of these cells contains in mind oh dear well I hit the mine game over and it should reset and it has done the text on the buttons isn't particularly clear so let's change the size of the font to make it more visible the wxwidgets frameworks makes this very simple for us I'm going to create an instance of WX font and tell it I want the size 24 and I can specify things like whether it's italicized and alized or bold or whatever and then for every single button I'm going to set the font to that instance and that's it let's see if that makes it look any better so here is my rate click yes there's a nice big one so one of these is a mine that one's not a mine and that's telling me that none of my surrounding cells our minds so it's this one however these three have to be mines because of this three here and this one has to be at mine and if those three are mines and these this is and this cell has to - that one can't be in mind so that one's safe it's a nice game this I like this a lot so all three of those in mines that can't be in mine and they can't be mines that can't be a mine that can't be a mine oh it gets very addictive I could play this all day anyway so this one must be a mine boom there we go I've only really scratched the surface of what you can do with graphical user interface applications and C++ in particular I've looked at the wxwidgets framework to help me with this it really does simplify things from having to do it yourself using the native operating system libraries i've also only looked at the most basic and trivial of controls and events there are probably combined thousands of different combinations which as a programmer you need to choose the most sensible ones to suit your application I'll probably follow this video up with a more advanced graphical user interface component video well we look at making our own graphical user interface components as it's often the case that you do need something a little bit more specific to express a particular set of information in a certain way that the native operating system can't provide and for the Linux viewers out there has looked tremendously Windows II but bear in mind this will be completely compatible code for code with a Linux compiling environment - I'll put these source files on the github but they won't work in isolation you will need to download and install the wxwidgets framework to get them to do anything useful now I know this video has been very introductory and it's been probably a little bit fast and it's skirted over some of the details but the best way to learn about these things is just to get stuck in and give it a go but if you've enjoyed it please give me a big thumbs up have a think about subscribing and I'll see you next time take care
Info
Channel: javidx9
Views: 619,327
Rating: 4.944849 out of 5
Keywords: one lone coder, onelonecoder, learning, programming, tutorial, c++, beginner, olcconsolegameengine, command prompt, ascii, game, game engine, pixelgameengine, olc::pixelgameengine, cross platform, graphical user interfaces, GUI, wxWidgets, QT, winapi, UWP, winforms, buttons, text boxes, listboxes, event handling, forms
Id: FOIbK4bJKS8
Channel Id: undefined
Length: 44min 49sec (2689 seconds)
Published: Sat Jun 15 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.