Blob Blame Raw
#include <iostream>
#include <utility>

#include <gdkmm/pixbuf.h>
#include <gtkmm/hvbox.h>
#include <gtkmm/image.h>

#include "generator.h"
#include "surface.h"

#include "mainwindow.h"


MainWindow::MainWindow():
	src_rect0   (new View::Point( Vector2(-10, -10) )),
	src_rect1   (new View::Point( Vector2( 10,  10) )),
	dst_rect0   (new View::Point( Vector2(-10, -10) )),
	dst_rect1   (new View::Point( Vector2( 10, -10) )),
	dst_rect2   (new View::Point( Vector2( 10,  10) )),
	dst_rect3   (new View::Point( Vector2(-10,  10) )),
	dst_bounds0 (new View::Point( Vector2(-20, -20) )),
	dst_bounds1 (new View::Point( Vector2( 20,  20) ))
{
	set_default_size(200, 200);
	
	Gtk::HBox *hbox = manage(new Gtk::HBox());
	hbox->set_homogeneous(true);
	
	src_view.points.push_back(src_rect0);
	src_view.points.push_back(src_rect1);
	src_view.signal_point_motion.connect(
		sigc::mem_fun(*this, &MainWindow::on_point_motion) );
	src_view.signal_point_changed.connect(
		sigc::mem_fun(*this, &MainWindow::on_point_changed) );
	src_view.signal_draw_view.connect(
		sigc::mem_fun(*this, &MainWindow::on_draw_src_view) );
	hbox->add(src_view);
	
	dst_view.points.push_back(dst_rect0);
	dst_view.points.push_back(dst_rect1);
	dst_view.points.push_back(dst_rect2);
	dst_view.points.push_back(dst_rect3);
	dst_view.points.push_back(dst_bounds0);
	dst_view.points.push_back(dst_bounds1);
	dst_view.signal_point_motion.connect(
		sigc::mem_fun(*this, &MainWindow::on_point_motion) );
	dst_view.signal_point_changed.connect(
		sigc::mem_fun(*this, &MainWindow::on_point_changed) );
	dst_view.signal_draw_view.connect(
		sigc::mem_fun(*this, &MainWindow::on_draw_dst_view) );
	hbox->add(dst_view);
	
	hbox->add(*manage(generator_demo()));
	
	add(*hbox);
	show_all();
}

Gtk::Widget*
MainWindow::generator_demo() {
	std::cout << "generator demo: generate" << std::endl;
	Generator generator;
	DataSurface surface(256, 256);
	generator.generate(surface, Vector2(0, 0), Vector2(16, 16));
	
	std::cout << "generator demo: convert" << std::endl;
	Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gdk::Pixbuf::create(
		Gdk::COLORSPACE_RGB, true, 8, surface.width(), surface.height() );
	guint8 *pixel = pixbuf->get_pixels();
	for(int r = 0; r < surface.height(); ++r) {
		Color *row = surface[r];
		for(int c = 0; c < surface.width(); ++c) {
			const Color &color = row[c];
			*(pixel++) = (guint8)(color.r*255.9);
			*(pixel++) = (guint8)(color.g*255.9);
			*(pixel++) = (guint8)(color.b*255.9);
			*(pixel++) = (guint8)(color.a*255.9);
		}
	}

	return new Gtk::Image(pixbuf);
}

void
MainWindow::on_point_motion(const View::PointPtr &/*point*/) {
	queue_draw();
}

void
MainWindow::on_point_changed(const View::PointPtr &/*point*/) {
}

void
MainWindow::on_draw_src_view(const Cairo::RefPtr<Cairo::Context> &context) {
	const Real ps = src_view.get_pixel_size();

	context->save();
	
	context->move_to(src_rect0->position.x, src_rect0->position.y);
	context->line_to(src_rect0->position.x, src_rect1->position.y);
	context->line_to(src_rect1->position.x, src_rect1->position.y);
	context->line_to(src_rect1->position.x, src_rect0->position.y);
	context->close_path();
	context->set_line_width(ps);
	context->set_source_rgba(1, 1, 0, 0.5);
	context->stroke();
	
	context->restore();
}

void
MainWindow::on_draw_dst_view(const Cairo::RefPtr<Cairo::Context> &context) {
	const Real ps = src_view.get_pixel_size();

	context->save();
	
	context->move_to(dst_rect0->position.x, dst_rect0->position.y);
	context->line_to(dst_rect1->position.x, dst_rect1->position.y);
	context->line_to(dst_rect2->position.x, dst_rect2->position.y);
	context->line_to(dst_rect3->position.x, dst_rect3->position.y);
	context->close_path();
	context->set_line_width(ps);
	context->set_source_rgba(1, 1, 0, 0.5);
	context->stroke();

	context->move_to(dst_bounds0->position.x, dst_bounds0->position.y);
	context->line_to(dst_bounds0->position.x, dst_bounds1->position.y);
	context->line_to(dst_bounds1->position.x, dst_bounds1->position.y);
	context->line_to(dst_bounds1->position.x, dst_bounds0->position.y);
	context->close_path();
	context->set_line_width(ps);
	context->set_source_rgba(1, 0, 0, 0.5);
	context->stroke();

	context->restore();
}