1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
// Osman Zakir
// 6 / 4 / 2017
// Bjarne Stroutrup: Programming: Principles and Practice Using C++ 2nd Edition
// Chapter 14 Exercise 5
// chapter14ex5.vcxproj -> main.cpp
// Exercise Specifications:
/**
* Define a Striped_rectangle where instead of fill, the rectangle is “filled”
* by drawing one-pixel-wide horizontal lines across the inside of the rectangle
* (say, draw every second line like that). You may have to play with the
* width of lines and the line spacing to get a pattern you like.
*/
#include <iostream>
#include <stdexcept>
#include "../../Graph.h"
#include "../../Simple_window.h"
namespace Graph_lib
{
class Striped_rectangle : public Rectangle
{
public:
Striped_rectangle(const Point &xy, const int width, const int height, const int stripe_width,
const Color &stripe_color);
void draw_lines() const override;
void set_stripe_color(const Color &color) { m_stripe_color = color; }
void set_stripe_width(const int stripe_width) { m_stripe_width = stripe_width; }
void set_width(const int width) { m_width = width; }
void set_height(const int height) { m_height = height; }
const Color stripe_color() const { return m_stripe_color; }
int stripe_width() const { return m_stripe_width; }
int width() const { return m_width; }
int height() const { return m_height; }
private:
Color m_stripe_color;
Lines m_striped_lines;
int m_stripe_width;
int m_width;
int m_height;
};
}
int main()
{
using namespace Graph_lib;
using std::runtime_error;
constexpr int win_x{ 100 }, win_y{ 100 };
const Point win_tl{ win_x, win_y };
constexpr int win_width{ 600 }, win_height{ 400 };
Simple_window win{ win_tl, win_width, win_height, "Striped Rectangle Class" };
try
{
constexpr int rect_x{ (win_width / 2) }, rect_y{ (win_height / 2) };
const Point rect_tl{ rect_x, rect_y };
constexpr int rect_width{ 400 }, rect_height{ 200 };
Striped_rectangle striped_rect{ Point{rect_tl.x - rect_width / 2,
rect_tl.y - rect_height / 2 },
rect_width, rect_height, 2, Color::blue };
striped_rect.set_color(striped_rect.stripe_color());
win.attach(striped_rect);
win.wait_for_button();
}
catch (const runtime_error &rte)
{
constexpr int text_x{ (win_width / 2) - 100 }, text_y{ (win_height / 2) - 15 };
const Point text_tl{ text_x, text_y };
Text err_msg_start{ text_tl, "Runtime Error: " };
Text err_msg{ Point{int((text_tl.x + err_msg_start.label().length() + 80)),
text_tl.y}, rte.what() };
err_msg_start.set_color(Color::black);
err_msg.set_color(Color::black);
win.attach(err_msg_start);
win.attach(err_msg);
win.wait_for_button();
}
}
Graph_lib::Striped_rectangle::Striped_rectangle(const Graph_lib::Point &xy, const int width,
const int height, const int stripe_width, const Graph_lib::Color &stripe_color)
: m_width{ width }, m_height{ height }, m_stripe_width{ stripe_width },
Graph_lib::Rectangle::Rectangle{ xy, width, height }, m_stripe_color{ stripe_color }
{
if (m_width <= 0 || m_height <= 0)
{
error("Bad rectangle: non-positive side");
}
if (m_stripe_width <= 0)
{
error("Invalid stripe width");
}
add(xy);
m_striped_lines.set_color(m_stripe_color);
m_striped_lines.set_style(Line_style(Line_style::Line_style_type::solid, m_stripe_width));
for (int i = 1; i < m_height / m_stripe_width; ++i)
{
m_striped_lines.add(
Point{ xy.x + 1, xy.y + i * m_stripe_width },
Point{ xy.x + m_width - 2, xy.y + i * m_stripe_width }
);
}
}
void Graph_lib::Striped_rectangle::draw_lines() const
{
Rectangle::draw_lines();
m_striped_lines.draw_lines();
}
|