#include "frame.h"
#include "pad.h"
#include "canvas.h"
#include <algorithm>
#include "exc.H"
#include <iostream>
using namespace std;
namespace blop
{
color pad::default_bordercolor_(0,0,0);
bool pad::default_draw_border_ = false;
length pad::default_borderwidth_(new length::base_id_t(terminal::LW));
bool pad::default_border_3D_ = false;
color pad::default_fillcolor_(1,1,1);
bool pad::default_fill_ = false;
pad &pad::fillcolor(const color &c)
{
fillcolor_ = c;
fill_ = true;
return *this;
}
color pad::fillcolor() const
{
return fillcolor_;
}
void pad::default_fillcolor(const color &c)
{
default_fillcolor_ = c;
}
pad &pad::fill(bool i)
{
fill_ = i;
return *this;
}
bool pad::fill() const
{
return fill_;
}
void pad::default_fill(bool i)
{
default_fill_ = i;
}
void pad::draw_border_bg(terminal *t)
{
vector<terminal::coord> cc;
if(fill_)
{
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(0.0,2)));
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(0.0,2)));
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(1.0,2)));
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(1.0,2)));
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(0.0,2)));
t->set_color(fillcolor_);
t->fill_polygon(cc);
cc.clear();
}
if(draw_border_)
{
if(!border_3D_)
{
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(0.0,2)));
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(0.0,2)));
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(1.0,2)));
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(1.0,2)));
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(0.0,2)));
t->set_linewidth(borderwidth_.termspecific_id());
t->set_color(bordercolor_);
t->set_linestyle(sym::solid);
t->draw_lines(cc);
}
else
{
length l1 = -1 * !borderwidth_;
length l2 = !cwidth() + !borderwidth_;
length l3 = !cheight() + !borderwidth_;
l1.specialize(t);
l2.specialize(t);
l3.specialize(t);
color c1(::min(fillcolor_.red()*0.5 + 0.5 , 1.35*fillcolor_.red()),
::min(fillcolor_.green()*0.5 + 0.5, 1.35*fillcolor_.green()),
::min(fillcolor_.blue()*0.5 + 0.5, 1.35*fillcolor_.blue()));
color c2(fillcolor_.red() * 0.8,
fillcolor_.green() * 0.8,
fillcolor_.blue() * 0.8);
t->set_color(c1);
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(0.0,2)));
cc.push_back(terminal::coord(l1.termspecific_id(),l1.termspecific_id()));
cc.push_back(terminal::coord(l1.termspecific_id(),l3.termspecific_id()));
cc.push_back(terminal::coord(l2.termspecific_id(),l3.termspecific_id()));
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(1.0,2)));
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(1.0,2)));
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(0.0,2)));
t->fill_polygon(cc);
cc.clear();
t->set_color(c2);
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(1.0,2)));
cc.push_back(terminal::coord(l2.termspecific_id(),l3.termspecific_id()));
cc.push_back(terminal::coord(l2.termspecific_id(),l1.termspecific_id()));
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(0.0,2)));
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(1.0,2)));
t->fill_polygon(cc);
cc.clear();
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(0.0,2)));
cc.push_back(terminal::coord(l1.termspecific_id(),l1.termspecific_id()));
cc.push_back(terminal::coord(l2.termspecific_id(),l1.termspecific_id()));
cc.push_back(terminal::coord(terminal::id(1.0,1),terminal::id(0.0,2)));
cc.push_back(terminal::coord(terminal::id(0.0,1),terminal::id(0.0,2)));
t->fill_polygon(cc);
cc.clear();
}
}
}
void pad::print(terminal *t)
{
if(print_me_ < 2) return;
t->open_layer(layer_);
t->subpicture_begin(terminal::coord(cleft().termspecific_id(),
cbottom().termspecific_id()),
terminal::coord(cright().termspecific_id(),
ctop().termspecific_id()));
draw_border_bg(t);
for(vector<grob *>::size_type i=0; i<content_.size(); ++i)
{
content_[i]->print(t);
}
t->subpicture_end();
t->close_layer(layer_);
}
void pad::prepare_for_draw()
{
if(print_me_ < 1) return;
container::prepare_for_draw();
if(draw_border_) borderwidth_.register_me();
}
pad *pad::current_pad_ = 0;
void pad::cd_specific()
{
current_pad_ = this;
frame::current_ = 0;
for(unsigned int i=0; i<content_.size(); ++i)
{
if(frame *f = dynamic_cast<frame *>(content_[i])) frame::current_ = f;
}
}
pad &pad::borderwidth (const length &l)
{
borderwidth_ = l;
return *this;
}
const length &pad::borderwidth() const
{
return borderwidth_;
}
void pad::default_borderwidth(const length &l)
{
default_borderwidth_ = l;
}
pad &pad::bordercolor (const color &c)
{
draw_border_ = true;
bordercolor_ = c;
return *this;
}
color pad::bordercolor() const
{
return bordercolor_;
}
void pad::default_bordercolor(const color &c)
{
default_bordercolor_ = c;
}
pad &pad::draw_border(bool i)
{
draw_border_ = i;
return *this;
}
bool pad::draw_border() const
{
return draw_border_;
}
void pad::default_draw_border(bool i)
{
default_draw_border_ = i;
}
pad &pad::border_3D(bool i)
{
border_3D_ = i;
return *this;
}
bool pad::border_3D() const
{
return border_3D_;
}
void pad::default_border_3D(bool i)
{
default_border_3D_ = i;
}
pad::pad(const length &x1,const length &y1,
const length &x2,const length &y2,
bool is_canvas)
{
name("pad");
draw_border_ = default_draw_border_;
bordercolor_ = default_bordercolor_;
fill_ = default_fill_;
borderwidth_ = default_borderwidth_;
border_3D_ = default_border_3D_;
right(x2);
left(x1);
top(y2);
bottom(y1);
lmargin(!borderwidth_);
rmargin(!borderwidth_);
bmargin(!borderwidth_);
tmargin(!borderwidth_);
}
pad::~pad()
{
if(current_pad_ == this)
{
current_pad_ = 0;
frame::current_ = 0;
}
}
pad &pad::title(const var &t)
{
if(t.str() != "")
{
if(!find(&title_)) add(&title_);
title_.text(t);
title_.x(0.5).y(1.0+EX).align(sym::center,sym::bottom);
tmargin(blop::height(t)+2*EX);
}
else
{
remove(&title_);
tmargin(!borderwidth_);
}
return *this;
}
pad &pad::mknew(length x1, length y1,
length x2, length y2)
{
return mksub(x1,y1,x2,y2,canvas::current());
}
pad &pad::mksub(length x1, length y1,
length x2, length y2,
container &parent)
{
pad *p = new pad(x1,y1,x2,y2);
p->autodel(true);
parent.add(p);
p->cd();
return *p;
}
pad &pad::current()
{
if(current_pad_ == 0) return canvas::current();
return *current_pad_;
}
}