Reputation: 113
The problem says: Draw a box with rounded corners. Define a class Box, consisting of four lines and four arcs. So I wrote the below code for that exercise:
#include <Simple_window.h>
Simple_window win(Point(100,100), 600,400, "semi-ellipse");
struct Box: Shape{
Box(Point p, int ww, int hh): w(ww), h(hh)
{ add(Point(p.x-ww,p.y-hh)); }
void d_l() const //creating 4 lines
{
Line hrz1 (Point(150,100), Point(400,100));
Line hrz2 (Point(150,300), Point(400,300));
Line ver1 (Point(507,150), Point(507,250));
Line ver2 (Point(41,150), Point(41,250));
win.attach(hrz1);
win.attach(hrz2);
win.attach(ver1);
win.attach(ver2);
}
void draw_lines() const //creating 4 arcs
{
fl_arc(point(0).x,point(0).y,w,h,30,90);
fl_arc(point(0).x,point(0).y,w,h,270,330);
fl_arc(point(0).x,point(0).y,w,h,90,150);
fl_arc(point(0).x,point(0).y,w,h,210,270);
}
private:
int w;
int h;
};
int main()
{
using namespace Graph_lib;
Box b(Point(100,100),100,50);
win.attach(b);
win.wait_for_button();
}
When I ran it I faced this exception:
Unhandled exception at 0x757FE9D7 (ole32.dll) in test.exe: 0xC0000005: Access violation reading location 0x00000004.
I know this refers to declaring Simple_window win(Point(100,100), 600,400, "semi-ellipse");
in global state. But I did that because I had to do it. The problem is that how to attach lines and also object (here b
) to Simple_window win
in either parts (main()
function and also Box
struct).
Upvotes: 2
Views: 1064
Reputation: 6467
Your lines are hard coded and independent of the constructor parameters. They could be drawn using directly the FLTK library, similarly with the arcs and placed inside the inherited from class Shape
and overriden function void draw_lines() const
. Then you don't need the window object to be pointer.
A possible implementation is:
Box::Box(Point p, int w, int h)
: width(w), height(h)
{
add(Point(p.x - w, p.y - h));
}
void Box::draw_lines() const
{
// draw lines with reduced length to adapt for the arcs
if (color().visibility())
{
// upper horizontal
fl_line(point(0).x + width/4, point(0).y, point(0).x + (3./4.) * width, point(0).y);
// lower horizontal
fl_line(point(0).x + width/4, point(0).y + height, point(0).x + (3./4.) * width, point(0).y + height);
// left vertical
fl_line(point(0).x, point(0).y + height/4, point(0).x, point(0).y + (3./4.)*height);
// right vertical
fl_line(point(0).x + width, point(0).y + height/4, point(0).x + width, point(0).y + (3./4.) * height);
}
// draw arcs
if(color().visibility())
{
fl_color(fill_color().as_int());
// upper left arc
fl_arc(point(0).x, point(0).y, width/2, height/2, 90, 180);
// upper right arc
fl_arc(point(0).x + width/2, point(0).y, width/2, height/2, 0, 90);
// down right arc
fl_arc(point(0).x + width/2, point(0).y + height/2, width/2, height/2, 270, 0);
// down left arc
fl_arc(point(0).x , point(0).y + height/2, width/2, height/2, 180, 270);
}
}
Upvotes: 0
Reputation: 939
You don't need to put anything in global space at all. You want to be passing information to the classes that need them as opposed to needing everything declared in global scope before you do anything with it.
What I write here modifies your Box
class so that it also has a private member variable which is a pointer to a Simple_window
class. The constructor is modified so that when you construct Box b
you have to send it a pointer to the Simple_window
in which it will be drawn. When you do this the pointer is assigned the pointer to the then declared Simple_Window win
.
#include <Simple_window.h>
struct Box: Shape{
private:
int w;
int h;
Simple_window* window;
public:
Box(Point p, int ww, int hh,Simple_window* win_): w(ww), h(hh),window(win_)
{ add(Point(p.x-ww,p.y-hh)); }
void d_l() const //creating 4 lines
{
Line hrz1 (Point(150,100), Point(400,100));
Line hrz2 (Point(150,300), Point(400,300));
Line ver1 (Point(507,150), Point(507,250));
Line ver2 (Point(41,150), Point(41,250));
window->attach(hrz1);
window->attach(hrz2);
window->attach(ver1);
window->attach(ver2);
}
void draw_lines() const //creating 4 arcs
{
fl_arc(point(0).x,point(0).y,w,h,30,90);
fl_arc(point(0).x,point(0).y,w,h,270,330);
fl_arc(point(0).x,point(0).y,w,h,90,150);
fl_arc(point(0).x,point(0).y,w,h,210,270);
}
};
int main()
{
using namespace Graph_lib;
Simple_window* win = new Simple_window(Point(100,100), 600,400, "semi-ellipse");
Box b(Point(100,100),100,50,win);
win->attach(b);
win->wait_for_button();
}
Upvotes: 1
Reputation: 8257
Looks like it is caused by the global creation of win. I have never run an FLTK program where anything graphical is created before main but I'm guessing that sometimes the graphics libs require some things to be in place so it is best to use them after main.
What can you do about it? If win is declared as a pointer and created inside main instead of outside main, then you won't get a crash.
...
Simple_window* win;
struct Box: Shape
{
...
win->...
...
}
int main()
{
win = new Simple_window(Point(100, 100), 600, 400, "semi-ellipse");
Box b ...
win->attach ...
win->wait ...
delete win;
}
Upvotes: 1