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.