Showing posts with label fltk. Show all posts
Showing posts with label fltk. Show all posts

Monday, 24 July 2023

Dev Diary // FLTK & Tetris Part 2

A little while ago I had fun making Tetris in FLTK; a library not meant for games.

It worked perfectly except for the bad flickering that I thought was down to the fact that FLTK just wasn't designed to handle games.

Then today I was working (as usual), and I saw a some code in Unreal Engine called double buffer and a light bulb went off in my head. When using something like Direct X, you usually set up a swap chain, and a buffer and a second buffer and all that jazz because the whole point is to draw your next frame to an unseen buffer, then you swap the unseen buffer with the one currently being displayed; ad infinitum. 

I wondered if this was the actual issue and the flickering was being caused by screen tearing. Turns out, it was. I had a look at the FLTK documentation and they have a solution for this!

Fl_Double_Window is a type of Fl_Window, so seeing as how my Window wrapper is a wrapper around Fl_Window, I just inherited from Fl_Double_Window instead and voila! No more flickering; it just works™.

FLTK and Tetris using C++ - Using FL Double Window to prevent screen tearing

This made me very happy. It's very smooth now and it's actually got me excited for my planned Game Engine: Blink. What can I create now? I could do anything.

Monday, 17 July 2023

Chapter 26 // Exercise 9, 10 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2019 and a modified version of the std_lib_facilities header found here.

Chapter 26 // Exercise 9

Add a text-based output format for the graphics interface library. For example, when a call Circle{Point{0,1},15} is executed, a string like Circle{Point{0,1},15} should be produced on an output stream.

For this, I didn't know if he meant output to the window (so a cout stream of sorts) or output it to a file (so ostream). So I decided on an output file based on the next exercise.

I used my "FLTK Engine" for this exercise again:

And added a simple call to output to a text file called DebugCommandsCalled. You can find this change in Window.cpp Blink::Window::onTextEnteredInCommandConsole().

Chapter 26 // Exercise 10

Use the text-based interface from exercise 9 to write a better test for the graphical interface library.

Github:  N/A

So we don't have any tests to start with for the FLTK code and I can't really imagine how using text files would be useful in the long run. I'd be much more inclined to add google tests to the project and start using that instead.

Sunday, 16 July 2023

Chapter 26 // Exercise 8 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2019 and a modified version of the std_lib_facilities header found here.

Chapter 26 // Exercise 8

Add a text-based interface to the graphics interface library from Chapters 12-15. For example, the string Circle{Point{0,1},15} should generate a call Circle{Point{0,1},15}. Use this interface to make a "kid's drawing" of a two-dimensional house with a roof, two windows, and a door.

So I cheated on that first graphics exercise back in Chapter 12 Exercise 7 and drew it in paint. Then loaded it as an image.

I had recently though, re-written the helper code from Bjarne into my own library of sorts (Adventures With Tetris) so going back to that messy, all over the place code from 2020 was jarring. Graph is so big now, if you make a change to it, compilation time is actually noticeable as everything includes Graph.h.

The re-write was the start of a planned FLTK Game Engine I named "Blink". You can find it here:
Apparently Blink is already the name of a HTML engine, however it's developed by Google, so it'll probably be dead in a few years.
(EDIT 09/10/2023 - I've now renamed the engine BLNK)

For this exercise I thought it would be useful to open a "console command" box when you hit a button on the keyboard. Like in Unreal Engine when backtick is pressed you can enter console commands.

This also seemed like a useful thing to add to the engine, so using UE for inspiration, I created a BasicInputBox which is a widget that takes in text and you can grab the contents of the box in various formats (int, string, double etc). I then added an instance of a BasicInputBox to a Window calling it a "CommandConsole". 

I then overrode Fl_Window::handle() to listen for keyboard events. When backtick is pressed it simply shows the widget, making it look like the console window has been opened. You can type text into it. Then with the focus still in that widget, you press enter and the callback function associated with the widget is triggered. The callback grabs what's in the box and uses it in someway. So for example, if you pass "r.drawCircle 100 100 50" to the Command Console, it draws a Circle at x100, y100 with a radius of 50.

Chapter 26 // Exercise 8 - Principles & Practice Using C++

I then got bored of the task as I really want to get this book finished...someday. And so I added a quick method for Images. "r.drawImage 100 100 house.png" draws the image specified in the last parameter at x100, y100. Mirroring what I did in chapter 12 exercise 7 all those years ago.

Chapter 26 // Exercise 8 - Principles & Practice Using C++

It's not perfect. I'd prefer to not have the window control what the command console does. A future task would be to send the info to a Console Manager along with the window. Using callbacks it can then call the appropriate callback, send the window in and the type can draw to the window. Or you can do something else, like change the colour of the background.

Tuesday, 14 March 2023

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

A colleague introduced me to the YouTube channel javidx9 the other day with the video:

I sat down after a gym session one dreary monday night and the 36 minute video took me about 90 minutes but javid had delivered and there was Tetris in the console window in about 300 lines of code. I also really enjoyed the little maths trick he employed to rotate the tetromino pieces. I found the video to be a bit rushed in places and some things cut out so I had to refer to the github repo quite a bit. Some things also went unexplained and me from a few years ago would be quite confused but on the whole; a solid tutorial.

Tetris was on my list of games to clone as it's a classic, easy-ish to implement and rife for tinkering. And tinkered with that initial small program I have.

Console Window
Here is the repo for my "all-in-main" version that I wrote whilst following along with the video. It's not exactly as his code but close enough:

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

++Console Window
I then set about taking this apart and creating a more generic Tetris that could eventually be run using any library. This one still runs in the console window but the input options, rendering, tetromino mechanics have been abstracted to work regardless of what library you're using....in theory.

FLTK
This is a small lightweight API  that I was introduced to whilst working my way through Principles & Practice. I actually really like it due to it's simplicity and Windows 95 looking graphics. This was the first test to see how portable I'd made my code in the previous exercise.

I started off modifying the wrapper code given in the book Programming: Principles & Practice by Bjarne Stroustrup. I've been meaning to do this for a while; it's not a perfect wrapper but it makes iteration in FLTK a bit faster.

Here's the repo:

With that done, I then found a free Tetris block png off the internet:

I used GIMP to change the hue of it to create 6 other colours.
Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

I then created a simple window with a quit button.

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

Now I needed to find a way to display the Tetris Board on the window. At this point I already had all of the code needed from the console versions so I created a grey block and wherever '#' is drawn, I told it to draw a grey block instead.

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

Next was to draw the current piece. This required some tweaking but after some trial and error I managed to get it working without having to expressly tell the individual blocks to draw to make up the shapes (it used the text created in the console versions).

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)


I then started copying over all the update logic to move and rotate the pieces. I was extremely surprised that this "just worked". FLTK does have it's own Keyboard event handling system however, the default windows one worked just fine with it so I stuck to that instead of changing it.

To create the "game loop", I used FLTK's timing system and registered a "tick" function with it. The tick function updates the Tetris board then redraws it. The tick function also handles updating the game tick counter to regulate tetromino speeds and locking them in place:

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)
Please ignore the flickering; FLTK and my screen recorder don't get along.

The only thing left after all this was to print out the score:

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

And with that I got bored and got the itch to do something else. I will come back to this though as I'd like to do it in SFML next, add sounds and such. I was happy I managed to get a "game" of sorts working in FLTK though as that library is not built for games....and it really shows. It was fun creating helper classes though. I'd like to know why it's flickering so much once the screen gets really full. I think it'd be a good task to delve into Visual Studios performance profiling and debugging options.

EDIT 25/07/2023
I fixed the screen flickering:

Tuesday, 4 January 2022

Chapter 22 // Exercise 16 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2019 and a modified version of the std_lib_facilities header found here.

Chapter 22 // Exercise 16

Modify the program from the previous exercise so that it reads a file (name,year(ancestors)) tuples, such as (Fortran,1956()), (Algol,1960,(Fortran)), and (C++,1985,(C,Simula)), and graphs them on a timeline with arrows from ancestors to descendants. Use this program to draw improved versions of the diagrams in section 22.2.2 and section 22.2.7.

Github: 

Out of all the exercises and drills we've done so far; this is the one I hate the most. It's stuff like this that makes me detest graphics programming and so for the second time in 6 years of trying to finish this book I'm skipping an exercise.

I did go back and finish the other one though so eventually I'll finish this one too. I will say, I went back and tried to use my scattergraph class and what a mess. I don't know how it worked in the first place.

To be continued...

Friday, 22 October 2021

Chapter 21 // Exercise 15 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2019 and a modified version of the std_lib_facilities header found here.

Chapter 21 // Exercise 15

Provide a GUI for the program from the previous exercise.


Oh this took an hour of just pure ctrl+c ctrl+v slight edit. I'm not surprised the creators of FLTK created Fluid, creating forms is tedious. But I powered through and I'm happy with the result.

FLTK Forms Chapter 21 // Exercise 15 - Principles & Practice Using C++

I did it! I managed not to procrastinate as much with this chapter and got it done in just under a month. With that I'm finally onto a chapter I've been looking forward to.

Tuesday, 19 October 2021

Chapter 21 // Exercise 12 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2019 and a modified version of the std_lib_facilities header found here.

Chapter 21 // Exercise 12

Provide a GUI interface for querying a file of Orders; e.g., "Find all orders from Joe," "Find the total value of orders in file Hardware," and "List all orders in file Clothing." Hint: First design a non-GUI interface; then, build the GUI on top of that.

Github: 

So the non-gui version can be found here:

I started to implement searching name, address, date and purchases, however it started taking up too much time and he only says name so I cut it back.

Chapter 21 // Exercise 12 - Principles & Practice Using C++

For the GUI version, I designed a new window called QueryOrderWindow and delved into a new FLTK widget; Fl_Text_Display. This class allows you display multiple lines of text with scrolling capabilities and other things but I only wanted to scroll.

I went over to GUI.h and added a new child of Widget called MultilineScroll_Outbox which creates an FL_Text_Display and Fl_Text_Buffer. You can then simply add text to the buffer. After that it was simply a matter of adding some buttons and pushing text to various places.

FLTK text Display scroll Chapter 21 // Exercise 12 - Principles & Practice Using C++

Sunday, 10 October 2021

Chapter 21 // Exercise 11 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2019 and a modified version of the std_lib_facilities header found here.

Chapter 21 // Exercise 11

Provide a GUI interface for entering Orders into files.


I hate that he made this exercise. I also hate the next exercise. I've not used FLTK in so long. I've changed pc's since I last used it and I'm glad I made myself a guide. Having been about 9 months since I last used the fltk solution I had of course forgotten how everything worked. I appreciate though that he makes you do exercises using fltk later on.

I got a bit pedantic with this one but eventually settled on a system that allows you to add purchases and then checkout when you're done. When you checkout it clears everything and allows a new customer to be added. When you quit the program; it prints out all the orders to a text file. Thanks to stringstreams, I didn't need to change any input/output in the actual order file apart from changing ifstream to istream in one place.

FLTK Input Form - Chapter 21 // Exercise 11 - Principles & Practice Using C++

Chapter 21 // Exercise 11 - Principles & Practice Using C++




Friday, 26 February 2021

C++ & FLTK // Adding Simple "Sprite" Support

This isn't really a tutorial, more of a "hey, I wanted to add 'sprites' to my FLTK build, how would I do that?"

For those of you new to my blog, I've been working my way through Bjarne Stroustrup's Practice & Principles using C++ in which there are several chapters focused on graphics programming. For this he supplies a couple of helper files that wrap some fltk features in a "higher level bow" so to speak. Over the months I've been editing these quite a bit to create my own shapes and add other functionality.

After these graphics chapters ended, I started to wonder if I could make a 2d engine using fltk and what does every good 2d engine need? Sprite support.

After an hour of tinkering, I had achieved this:

C++ & FLTK - Adding "Sprite" Support

Very exciting. I'd like to note, this did not capture well and it kind of looks like there's a slight stall after a few frames but when running the program it's fine.

So I first went about this by creating a new simple window that supports "ticking". It has a quit button and a tick function that's registered with fltk's callback system to run every 0.1 seconds.

Then I made a new class called Sprite which inherits from the Shape class. I soon learnt that Shape is great for basic stuff, but when you want to start doing event based game stuff, the way shapes are drawn and updated is kind of clunky so I need to re-do shapes. But for now I worked round it.

So a Sprite takes in a point to draw from the top left-hand corner, a file name, frame width, frame height and the number of rows in the spritesheet; kind of reaching for the moment as it can't deal with sprites with multiple rows just yet.

The Sprite itself is just an Fl_Image that holds the png "spritesheet". This was mine:

C++ & FLTK - Adding "Sprite" Support

It's the coin blocks from Super Mario World. When attaching this image to the window, obviously the entire image was displayed. Sprites should be able to only display a certain portion or 'frame' of their spritesheet, so I made a function called drawFrame() that takes in a frame number. This frame number is stored and used in draw_lines() to display a particular part of the image. This is the annoying part of using a Shape; I must override draw_lines() and use that to draw. 

To only display a certain part of the image, you can just use built-in functionality of Fl_Image. The draw() function allows you to specify a part of the image to draw by passing in the top left corner locations and an offset. This essentially "crops" the image to the size given. The width and height is then multiplied by the frame number each frame to advance it to the next image:
C++ & FLTK - Adding "Sprite" Support

C++ & FLTK - Adding "Sprite" Support

Here, my spritesheet is 200x400 pixels with each block being 40x40. Therefore, to play an animation, fltk is told to start at frame 0 and increase by 1 each frame until it hits 3, then go back to 0. This stops it from showing the brown block, which is frame number 4.

So to show the second image block, it would do 40 * 1, which is 40. This gives an x offset of 40. Then the x and y coordinates of the new cropped image are obtained by getting the top left of the full sprite sheet (I set it to 50, 50) then adding on the offset; making the new draw point 90, 50. The draw() function is handy though as it can display the cropped image in the same position as the last through the first two parameters. The Y offset is ignored right now as we don't have multiple rows.

It's also important that post increment is used here. I usually detest using post++, however here it is necessary as the current frame needs to be drawn before it's incremented. If it was ++frame, then the next frame would be drawn as it's incremented before use.

And that's pretty much it for creating the most basic of basic sprite systems for FLTK. I have plans to rewrite the shape class so I have full control over how they're drawn.

You can find the full code for this project here along with a project file:

Sunday, 20 September 2020

Chapter 16 // Exercise 10 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 10

Provide a program where you can choose among a set of functions (e.g., sin() and log(), provide parameters for those functions, and then graph them.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%2010

It turns out In_box::get_int() will not correctly return negative numbers. This was because of the check to see if a number had been placed in the box. It checks the first character and if it's not a number it returns -99999 so I changed it to allow the first character to be '-'. Other than that, thanks to the Stored Function we made in the last chapter, this was quite straightforward. 

Chapter 16 Exercise 10 Principles & Practice Using C++

And the graphics chapters are now over :( Although I am excited to finally start working on algorithms and memory management. I use these concepts a lot at work but I feel like I haven't picked up the basics properly and I had to start running before I could even walk. I've had a look through the rest of the exercises and there are more that use FLTK so it hasn't completely disappeared. 


Friday, 18 September 2020

Chapter 16 // Exercise 9 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 9

Modify the calculator from Chapter 7 to get its input from an input box and return its results in an output box.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%209

Oh I wish this chapter would stop haunting me. Looking at the code though reminds me of how eager I was to put in error messages. Now I just don't care.

I also wanted to avoid messing with get() and unget() as much as possible so I googled how to put a string into cin and found this very handy section of code:

This uses istringstreams and effectively "fakes" typing in the keyboard. The calculator code thinks we've typed into cin and will happily go about getting and putting back characters in cin.

I did remove a few functions and moved definitions into a cpp file (with declarations in the header) but for the most part it has stayed intact from the code uploaded here:

You can both type statements into the calculator (just don't type '=' press the button) and press the buttons:

Chapter 16 // Exercise 9 - Principles & Practice Using C++




Wednesday, 16 September 2020

Chapter 16 // Exercise 8 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 8

Provide a currency converter. Read the conversion rates from a file on startup. Enter an amount in an input window and provide a way of selecting currencies to convert to and from (e.g., a pair of menus).

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%208


I'm not sure how but I did it. It took me a good hour of staring at the documentation and this very helpful post from 2007:
http://www.murga-projects.com/forum/showthread.php?tid=122

My excitement though is not because I created a currency converter but, I enabled the Window class to use a jpg image as a background for the window. 

Chapter 16 Exercise 8 - Principles & Practice Using C++

In all of the previous exercises, you may have noticed that images always draw on top of widgets, no matter what order you draw in. There is a hack however, and that is to create an Fl_Box, give the box an image and then attach the box to your window. Sounds good. The problem though is that we are using Bjarne's helper classes which do not have any functionality to support this so I had to add it.

I basically made a new Widget called FakeBkg that holds an Fl_Image. attach() needs to be overridden as it's pure virtual. In here I assigned a new Fl_Box to the Fl_Widget stored in Widget, gave the widget the image stored in FakeBkg and then assigned the window with my window...I think I might do a separate post on this one.

Anyway, I added a new function to In_box to handle getting floats out of a text box and used a fixed size text file which kind of feels like cheating. I know exactly what line the conversion rates are on and how many characters in so my switch statement is extremely hard coded but efficient. Instead of reading in the text file at the beginning and storing all the different formats (which may or may not get used), it gets the rate from the file when needed.

Monday, 14 September 2020

Chapter 16 // Exercise 7 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 7

Using the techniques developed in the previous, make an image of an airplane "fly around" in a window. Have a "Start" and a "Stop" button.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%207


As I learnt in the last exercise; FLTK does not directly support rotating images (it is something that you need to implement yourself and well... I can't be bothered). So, this is a very "basic" implementation of just moving a png image round the window.

FLTK does support image mirroring however it's when using its Direct Draw functions which we're not using. So, I have two images and the images are switched out when at certain angles for added "realism". Disgustingly hacky but there you go. Stopping and starting the plane is quite simple. I just moved adding the timeout to start and then removing it on stop.

Chapter 16 // Exercise 7 - Principles & Practice Using C++


I used an ellipse for the "track" as it has the useful functions getPointDirection() and getPointOnEllipse(). Ellipse could easily be switched out for a super ellipse though and given random values for the plane to follow random tracks. 

I take all the captures using the windows game bar, it seems to add blips for some reason. The program runs smoothly though.


Sunday, 13 September 2020

Chapter 16 // Exercise 6 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 6

Make an "analog clock," that is, a clock with hands that move. You get the time of day from the operating system through a library call. A major part of this exercise is to find the functions that give you the time of day and a way of waiting for a short period of time(e.g., a second for a clock tick) and learn to use them based on the documentation you found. Hint: clock(), sleep().

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%206


The most annoying thing about this exercise was learning that FLTK doesn't support rotating images. There is a way to implement it yourself but it involves getting all the pixel data and shifting it yourself to the new location and I can't be bothered. So I ended up just using some arrows which don't look great but they do the job.

Next I implemented the clock moving. It has three hands; one for hours, minutes and seconds. They use the C struct tm* which handily contains the current date in nice formats. AnimatedClock is its own shape and pretty much handles itself. ClockWindow has a member variable of type AnimatedClock and then ticks every second. In the gif, my PC clock was at 13:38 when I started the recording:



Originally I was trying to use Sleep(), which is a function specific to Windows that pauses the program for a given amout of milliseconds. This did not work how I wanted it to. FLTK has it's own built in timer system called Fl::Wait, we've already used it a few times before. I had a look at the documentation to see if there was a version of wait that takes in a "time value" and there is:
https://www.fltk.org/doc-1.4/classFl.html#af49654e35a0b636aa751dce5ff88a7f5

Here it mentions idle callbacks (i.e our button presses) and elapsed timeouts. I had another look round the documentation for what this meant and  found this:
https://www.fltk.org/doc-1.3/classFl.html#a23e63eb7cec3a27fa360e66c6e2b2e52

The two functions we are interested in are Fl::add_timeout and Fl::repeat_timeout. Using these are somewhat similar to registering tick functions in UE4 (the concept is essentially the same).

Fl::add_timeout requires 3 arguments; a time in seconds, a callback function and a reference to the object. So first, we register the new timeout in the constructor of our window:
(void*)this is very important otherwise on the next tick, fltk will not know what object you are referring to and you will most likely get a runtime error saying you are trying to access a nullptr.

We now create the call back function:
As standard we cast the given address to our window type and call the function we want calling when our timer elapses. The next line calls Fl::repeat_timeout, this is because Fl::add_timout is a oneshot and as such it will only be called once so we tell fltk to repeat the timeout every given time. This is useful because you might want it initially to go off for 1 second but then check every 10. We give it the callback function and use addr to specify our object. addr contains the address of this (our window) which we passed in in the constructor.

Thursday, 10 September 2020

Chapter 16 // Exercise 5 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 5

Write a program that draws a shape of your choice and moves it to a new point each time you click "Next". The new point should be determined by a co-ordinate pair read from an input stream.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%205


Another straightforward one. I added a next button & action function to the window created in the previous exercise and had it draw a randomly sized/shaped/coloured star. If no co-ordinates are given, it chooses a random one. In In_box::get_int(), it always returns -999999 if no number is given so I plugged that in as no number given.


Chapter 16 // Exercise 5 - Principles & Practice Using C++

Wednesday, 9 September 2020

Chapter 16 // Exercise 4 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 4

Make a menu with items that make a circle, a square, an equilateral triangle, and a hexagon, respectively. Make an input box (or two) for giving a coordinate pair, and place the shape made by pressing a menu item at that coordinate. Sorry, no drag and drop.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%204


This was tricky because the window constantly calls draw() which appears to be causing problems. When you add a new shape to the window it seems to overwrite the previous one with garbage, causing problems when it comes to redraw the scene.

For some strange reason, I had to make everything a pointer in order for it to work properly. I'm not quite sure why but I have a hunch. Even though I was pushing back instances of Shapes into a vector stored in the window; the previous shapes were going out of scope when redraw() was called. This would explain why the vector suddenly becomes filled with garbage. It knows a Shape used to be there but it doesn't know what. To get round this, I new-ed the shapes up and pushed them into a vector of Shape pointers. This ensures that the shapes cannot go out of scope.

Once again I had one function that handled the button press and used an enum to tell the function what shape to draw.


Chapter 16 // Exercise 4 - Principles & Practice Using C++



Tuesday, 8 September 2020

Chapter 16 // Exercise 3 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 3

Place an Image  on top of a Button; move both when the button is pushed. Use this random number generator from std_lib_facilities.h to pick a new location for the "image button":

#include <random>

inline int randint(int min, int max)
{
    static default_random_engine ran;
    return uniform_int_distribution<>{min, max}(ran);
}

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%203


This one was quite straightforward. I'm a little surprised at just how easy it is to get movable buttons up and running using fltk, it's a bit of a nightmare in DirectX. I modified My_window slightly to have another button and an image and changed the move() function in widget so it actually moves it to a new location instead of adding the new location to the current one.


Chapter 16 // Exercise 3 - Principles & Practice Using C++

Monday, 7 September 2020

Chapter 16 // Exercise 2 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 2

Make a window (based on My_window) with a 4-by-4 checkerboard of square buttons. When pressed, a button performs a simple action, such as printing its coordinates in an output box, or turns a slightly different colour (until another button is pressed).

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%202


The main problem with this exercise is that I learnt that you cannot use a lambda as a callback function if it is capturing local variables. I managed to get rid of all the call back functions and have only 1 button action function but because of this constraint, I still had to have 16 separate push_backs in the constructor for CheckerboardWindow instead of being able to use a for loop.

I added a couple of new values to the Colour_type enum in Graph.h as well which gives us the exact background colour (handily called FL_BACKGROUND_COLOR by fltk). 

There was something oddly satsifying about this exercise though...maybe I can finally make Minesweeper live and reloaded now...


Chapter 16 // Exercise 2 - Principles & Practice Using C++

Wednesday, 2 September 2020

Chapter 16 // Exercise 1 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 1

Make a My_window that's a bit like Simple_window except that it has two buttons, next and quit.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%201

I could've easily just inherited Simple_window and added another button to it but I wanted to practice making a window so created it in a new file.

My_window doesn't work exactly like Simple_window and needs return gui_main() to work properly (unlike Simple_window) but I like it.

Chapter 16 // Exercise 1 - Principles & Practice Using C++

The green square appears after next is pressed.

Tuesday, 1 September 2020

Chapter 16 // Drills 1, 2, 3, 4 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Drills 1, 2, 3, 4

1. Make a completely new project with linker settings for FLTK (as described in Appendix D).
2. Using the facilities of Graph_lib, type in the line-drawing program from section 16.5 and get it to run.
3. Modify the program to use a pop-up menu as described in section 16.7 and get it to run.
4. Modify the program to have a second menu for choosing line styles and get it to run.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Drills

I didn't do 1 as I've been using the same project since the start of chapter 12 because I'm lazy.


The second one made me scratch my head a few times. I initially set it up in Graph.h but it didn't like that. So I moved it to Simple_window.h...visual studio also didn't like that. It didn't like it in Window.h either. Eventually, because I'm big brain, I realised I was creating circular dependencies due to certain headers that needed to be included so Lines_window is in GUI.h. Also, because Window is a class and not a struct, make sure you put : public Window when inheriting....

3 is pretty simple as long as you follow the code in the book however you need to add hideMenu() and redraw() to the change() function otherwise the menu won't close itself after you've selected a new colour.

Once 3 was working, 4 was as simple as copypasta and change some code. I decided not to implement callback functions and use lambdas as I hate them and I need to get more comfortable using them..even if I think the callback functions are more readable. Unreal Engine fucking loves lambdas. I made the change line style function take in a line style so I didn't have to create a function for every different line style.


I'm happy to have finally started this chapter though; I'm going to create some sick 1998-looking programs now.