Showing posts with label fixing files. Show all posts
Showing posts with label fixing files. Show all posts

Wednesday, 5 August 2020

Notes on Chapter 15 // Principles & Practice using C++

So I've been reading though this chapter and got stuck on section 15.5 where he uses a lambda expression to capture some data. The code can be seen on page 533. Here he uses Function to graph another function however I got the following error when entering the code myself:

error C2440: 'initializing': cannot convert from 'initializer list' to 'Graph_lib::Function'

I triple checked the code in the book and my code and there was no difference. Unfortunately no one else seemed to have encountered this exact problem. I eventually fixed it with some guidance from this stackoverflow post: https://stackoverflow.com/questions/36030589/i-cannot-pass-lambda-as-stdfunction

In Graph.h, the struct Function has just one constructor, with the first argument being of the type Fct. Now Fct is a typedef of a function called Fct that takes in a double and returns a double. Unfortunately, Visual Studio did not like this and would not convert the lambda expression to fit. In order to get round this, I created a new constructor that instead takes in a std::function called f that takes in a double and returns a double:


Visual Studio was happy with this and built the solution.

Fixing Window label bug
EDIT 18/08/2020 - Please read the edit down below.

I also finally fixed the weird thing that was going on with the window label. After you click next it always disappeared for me or started displaying garbage. I looked into this and found that FLTK eventually relies on this constructor for label:

void Fl_Window::label(const char *name) {
  label(name, iconlabel()); // platform dependent
}

When it calls iconlabel() it goes here:

  /**  See void Fl_Window::iconlabel(const char*)   */
  const char* iconlabel() const {return iconlabel_;}

iconlabel_ is null. This is in Fl_Window.H which I am reluctant to modify. It appears that in our Window.h, Window is calling the constructor for label and passing a char array to it. However it is not setting up the icon label.

void set_label(const string& s) { label(s.c_str()); }


iconlabel_ is set to 0 in the constructor for Fl_Window(). To fix this, it is a one line change in Window.h:

void set_label(const string& s) { label(s.c_str()); show(); }

After trying to set iconlabel_ manually it took me to another function which checks to see if the window is to be shown. It returned false. show() is a function set in GUI.h and is only called once upon initialisation of the window (which is why the label correctly displays upon first viewing). The problem is that when the label is changed we need to call show() again otherwise iconlabel_ will not be updated.

EDIT 18/08/2020 - Nothing can ever be simple. Whilst doing exercise 2 of Chapter 15, I noticed the label would go missing again if the next button was pressed to be replaced with garbage. I had a look and even just after the window has been created it's showing the title label as null. I tried setting the label in the window init() function, changing the label in the Fl_wait loop but the label was always null.

I then noticed that Fl_Window wants a const char* in it's constructor:
In C, you can use char* as strings. char* will always point to the first character in the string. Our Window and Simple_window uses a string& and then converts that to a char* using the .c_str() function. This should work just fine but in case there was something being lost in translation, I changed all the string& references to const char*. Now, it's displaying labels correctly and storing them in Fl_window. You don't need to call show() in set_label either as I changed that to take in a char* as well.

Fixing Default Line Colour

Another thing that was annoying me was that the default line colour was a light grey; this was impossible to see on the background and I was sick of always having to set the colour for everything. So I just set the default line colour to black in the constructor for Shape:
Shape() { set_color(Color::black); }

Friday, 13 March 2020

Notes on the examples in Chapter 12 Programming:Principles and Practice Using C++

So I've started reading through Chapter 12 and just trying to get the first example shown a page in took me a while. Therefore, I'll be leaving comments and fixes in this post for anyone else who may have struggled.

In order to get the program running in the first place you'll need some files made by Bjarne himself. I spoke about these in a previous post and fixed them up and posted them to my Git. There were a lot of errors as, due to time they have become wildly out of date.

These cleaned up files can be found here:
https://github.com/l-paz91/principles-practice/tree/master/Graphics%20Files

And I wrote about this process in detail here:
https://lptcp.blogspot.com/2020/03/programming-principles-practice-fixing.html

I wrote a guide for installing FLTK here as well:
https://lptcp.blogspot.com/2020/03/how-to-install-fltk-for-use-with.html

12.3 - A First Example pg 415
Due to namespace ambiguity, it's probably best if you avoid using namespace Graph_lib. In the first example in 12.3, Polygon is considered ambiguous and requires Graph_lib even though the using keyword has been set.  That was the only issue I had for the first example.

12.7.3
Initially, the axis drew as light grey on my screen. I tried looking for the definition but I couldn't seem to find where it is initially set to use grey, so I just left it. I then remembered that we're supposed to be hitting "next" after every example to show it building up. The key is to make sure you have win.wait_for_button() after every example. The axis shows as black after that.

I also noticed that the canvas label disappears after the first screen. Odd. (edit 30/09/2020 - I ended up fixing this here: https://lptcp.blogspot.com/2020/08/notes-on-chapter-15-principles-practice.html)

12.7.5 - 12.7.6
Both Rectangle and Polygon will need their scope (Graph_Lib) when using them. Even if you have using namespace Graph_lib;

12.7.7
The green shade is much brighter than the one printed.

12.7.10
Ellipse also needs Graph_lib::

You can find the full code and images I used here:
https://github.com/l-paz91/principles-practice/tree/master/Chapter%2012/Examples

Thursday, 12 March 2020

Programming: Principles & Practice - Fixing Files for Chapters 12

Chapter 12 had quite a bit of setup to get it working (and to be able to complete the exercises). Bjarne never actually mentions that you need to download extra files in order to get his examples working. He says at the start of the exercises "you need these" but doesn't give any other information. You can find the custom classes he's created here:

Not all of these are necessary for the graphics chapters. I have a few notes on getting them to compile though as they are hilariously outdated and the internet only turned up bits and pieces for working versions, so I begrudgingly spent an entire evening going through every bloody error. You can find the cleaned up versions on my github however, in the interest of knowledge, try going through and fixing the files.

1 - There are 2 Gui.h (one is all capitals). Use the uppercase GUI.h.

2 - Simple_window.cpp relies on a custom constructor for the next_button(Point()) member. This has been commented out in the code. In Point.h un-comment the two commented out constructors.

3 - Graph.cpp is a red mess.

  • Include Window.h at the top. 
  • Around line 316, change bool can_open to ifstream can_open.
  • In Graph.h add #include <FL/fl_draw.H> and <FL.Fl_Image.H> for reasons. And yes, the f and the is lowercase for some absurd reason and one contains a slash, the other a dot....
4. Simple_Window has two versions of wait_for_button(). In Simple_window.h change void wait_for_button() to void wait_for_button_modified(). Then add  bool wait_for_button();  above it. (This is because, at the time of writing this, I'm not sure if the modified version will be used at some point).

5. Simple_Window has two definitions for it's constructor. Delete the one in the header file and replace it with:
  • Simple_window(Point xy, int w, in h, const string& title);
6. Window is the Windows handle for a hwnd, files are not happy about this. Put all the code in namespace Graph_lib {code here} for the following files:
  • Simple_Window.h
  • Simple_window.cpp
7. Simple_window...again. 
  • next() already has a body. Delete the body from the .h file so it just reads void next();
  • cb_next() also already has a body. Delete the one in the cpp file as, with a quick glance, the one in the header looks safer; pointer usage wise that is.
8. They're not errors but all the mismatch warnings are annoying me. Regardless of how annoying they are, the phrase "if at first you don't succeed, #pragma disable warning" is not the approach to take...(as much as I want to). Where it says '<' signed/unsigned mismatch; changed the int to unsigned int (or remove the unsigned) till the warnings go away. 

There are two more warnings on Graph.cpp warning about conversion from double to int...seeing as how Point only uses ints I'm guessing floating point maths is not allowed so I wrapped the second part in a static_cast<int>(u.first*(p2.x - p1.x)); etc. 

9. Only two errors left. Graph_lib::Menu::Menu(...) already has a body (of course it does). Delete the one in the cpp file (they're the same...practically). And fixing that fixed the last error and it builds...YEAHHH.


Alright, I think that will do for the evening. I've been sat here for 2 hours just trying to do the bloody example a page into the chapter. 

Full code files:

EDIT 14/12/2020
I've just realised, I never posted the original cleaned up version of SimpleWindow.cpp...Whoops. I never saved the original copies but over Christmas break I'll fix up a new copy.

EDIT 01/01/2021
The link to Bjarne's original files above no longer works...It took me a good 10 minutes to navigate his website and realise that the old files are now provided as a zip file here:

He notes that they were recovered from the loss of his previous website which must've gone down sometime last year. These new files are slightly different to ones I downloaded; they appear to be newer. This batch does not contain a Simple_window.cpp as everything is defined in the header: