Blob Blame Raw
#include "view.h"

#include <gtkmm/container.h>


void
View::Point::draw(
	const Cairo::RefPtr<Cairo::Context>& context,
	View &view )
{
	const Real ps = view.get_pixel_size();
	context->save();
	context->arc(position.x, position.y, radius*ps, 0.0, 2.0*M_PI);
	context->set_source_rgba(color.r, color.g, color.b, color.a);
	context->fill_preserve();
	context->set_source_rgba(0.0, 0.0, 0.0, color.a);
	context->set_line_width(selected ? 2.0*ps : ps);
	context->stroke();
	context->restore();
}


View::View():
	dragging()
{
	set_events(
		Gdk::POINTER_MOTION_MASK
	  | Gdk::BUTTON_PRESS_MASK
	  | Gdk::BUTTON_RELEASE_MASK );
}

View::~View() { }

Real
View::get_pixel_size()
	{ return 1.0/sqrt(fabs(transform.m00 * transform.m11)); }

bool
View::on_draw(const Cairo::RefPtr<Cairo::Context>& context) {
	context->save();

	const Real border_size = 1.0;
	const Real border_margin = 2.0;
	
	context->save();
	context->rectangle(0, 0, get_width(), get_height());
	context->set_source_rgba(0, 0, 0, 1);	
	context->fill();
	context->rectangle(
		border_margin, border_margin,
		get_width() - 2*border_margin,
		get_height() - 2*border_margin );
	context->set_line_width(border_size);
	context->set_source_rgba(1, 1, 0, 1);
	context->stroke();
	context->restore();

	context->translate(0.5*get_width(), 0.5*get_height());
	context->transform(Cairo::Matrix(transform.m00, transform.m10, transform.m01, transform.m11, transform.m30, transform.m31));
	signal_draw_view(context);
	for(PointList::const_iterator i = points.begin(); i != points.end(); ++i)
		(*i)->draw(context, *this);
	context->restore();
	return true;
}

bool
View::on_motion_notify_event(GdkEventMotion *event) {
	Vector2 position = Vector2(event->x - 0.5*get_width(), event->y - 0.5*get_height());
	if (dragging) {
		if (selected_point) {
			selected_point->position = Vector2(transform.invert()*Vector4(position + selected_point_offset));
			point_motion(selected_point);
			queue_draw();
		}
	} else {
		PointPtr point;
		for(PointList::iterator i = points.begin(); i != points.end(); ++i) {
			(*i)->selected = false;
			Vector2 point_position = Vector2(transform * Vector4((*i)->position));
			Vector2 offset = point_position - position;
			if (offset.square() <= (*i)->radius * (*i)->radius)
				point = *i;
		}
		if (point)
			point->selected = true;
		if (selected_point != point) {
			selected_point = point;
			queue_draw();
		}
	}
	return true;
}

bool
View::on_button_press_event(GdkEventButton *event) {
	if (event->button == 1)
		dragging = true;
	return true;
}

bool
View::on_button_release_event(GdkEventButton *event) {
	if (event->button == 1) {
		dragging = false;
		if (selected_point)
			point_changed(selected_point);
	}
	return true;
}