February 20,2009

Seed(2)

GObject、Gio、Gtk、Glib、Clutter 等在範例裡看到的 library,在 Seed 原始碼裡是看不到的,Seed 是利用 GObject Introspection 來跟這些 library 互動。 Cairo、sqlite、readline 的話,因為並沒有使用 GObject 這個 library,所以 Seed 另外寫 Module 來跟這些 library 互動,你可以在 Seed 原始碼的 modules 目錄下看到~ Cairo 實際上是在 Canvas 這個 module 裡,Canvas 裡共有四個主要的類別:CairoCanvas、PDFCanvas、SVGCanvas、ImageCanvas,創建這些 Canvas 以後,基本上都是使用 Cairo 來在這些 Canvas 上繪圖。裡面沒有封裝 cairo_pattern_xxxx、cairo_text_xxxx、cairo_mask...等函數,所以不能用 Cairo 來繪圖或是繪字。
#!/usr/bin/env seed

Seed.import_namespace("Gtk");
Seed.import_namespace("Canvas");
Seed.import_namespace("Gdk");

//
// Initialize GTK+
//
Gtk.init(null, null);

// Create the main application window and set the title
var window = new Gtk.Window({title: "Canvas Demo"});
var vbox = new Gtk.VBox();
var drawingArea = new Gtk.DrawingArea();
var status = new Gtk.Statusbar();
var hbox = new Gtk.HBox();
var exposeEvent = function() { return true;};

//
// create Cairo Canvas
//
function createCairoCanvas()
{
	var cairo = Gdk.cairo_create( drawingArea.window );
	return new Canvas.CairoCanvas( cairo );
}

// 
// Demos from http://cairographics.org/tutorial/
//
function strokeDemo()
{
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	canvas.strokeStyle = "rgb( 0, 0, 255 )";
	canvas.strokeRect( 10, 10, 50, 50 );
	canvas.stroke();
	return true;
}

function fillDemo()
{
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	canvas.fillStyle = "rgb( 0, 0, 255 )";
	canvas.fillRect( 10, 10, 50, 50 );
	canvas.fill();
	return true;
}

function fourColorDemo() {
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	canvas.strokeStyle = "rgb( 0, 0, 0 )";
	canvas.moveTo( 0, 0 );
	canvas.lineTo( 100, 100 );
	canvas.moveTo( 100, 0 );
	canvas.lineTo( 0, 100 );
	canvas.lineWidth = 10;
	canvas.stroke();

	canvas.fillStyle = "rgb( 255, 0, 0 )";
	canvas.globalAlpha = 0.8;
	canvas.fillRect( 0, 0, 50, 50 );

	canvas.fillStyle = "rgb( 0, 255, 0 )";
	canvas.globalAlpha = 0.6;
	canvas.fillRect( 0, 50, 50, 50 );

	canvas.fillStyle = "rgb( 0, 0, 255 )";
	canvas.globalAlpha = 0.4;
	canvas.fillRect( 50, 0, 50, 50 );
	return true;
}

function pathDemo() {
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	canvas.strokeStyle = "rgb( 255, 0, 0 )";
	canvas.beginPath();
	canvas.moveTo( 25, 25 );
	canvas.lineTo( 50, 37.5 );
	canvas.lineTo( 75, 25 );
	canvas.arc( 50, 50, 25*Math.sqrt(2), -0.25*Math.PI, 0.25*Math.PI, false );
	canvas.bezierCurveTo( 50, 37.5, 50, 62.5, 25, 75 );
	canvas.closePath();
	canvas.stroke();
	return true;
}

function scaleAndTransformDemo() {
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	canvas.strokeStyle = "rgb( 255, 0, 0 )";
	canvas.lineWidth=10;
	canvas.save();
	canvas.scale( 0.5, 1 );
	canvas.arc( 50, 50, 40, 0, 2*Math.PI, true );
	canvas.stroke();

	canvas.translate( 100, 0 );
	canvas.arc( 50, 50, 40, 0, 2*Math.PI, true );
	canvas.restore();
	canvas.stroke();

	return true;
}

// 
// Demos from http://cairographics.org/samples/
//
function arcDemo() {
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	var xc = 128;
	var yc = 128;
	var radius = 100;
	var angle1 = 45 * (Math.PI/180);
	var angle2 = 180 * (Math.PI/180);

	canvas.lineWidth = 10;
	canvas.arc( xc, yc, radius, angle1, angle2, true );
	canvas.stroke();

	canvas.fillStyle = "rgb( 255, 51, 51 )";
	canvas.globalAlpha = 0.6;
	canvas.lineWidth = 6;
	canvas.arc( xc, yc, 10, 0, 2*Math.PI, true );
	canvas.fill();

	canvas.arc( xc, yc, radius, angle1, angle2, true );
	canvas.lineTo( xc, yc );
	canvas.arc( xc, yc, radius, angle2, angle2, true );
	canvas.lineTo( xc, yc );
	canvas.stroke();

	return true;
}

function clipDemo() {
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	canvas.arc( 128, 128, 76.8, 0, 2*Math.PI, true );
	canvas.clip();
	canvas.beginPath();
	canvas.fillRect( 0, 0, 256, 256 );
	canvas.strokeStyle = "rgb( 0, 255, 0)";
	canvas.moveTo( 0, 0 );
	canvas.lineTo( 256, 256 );
	canvas.moveTo( 256, 0 );
	canvas.lineTo( 0, 256 );
	canvas.lineWidth = 10;
	canvas.closePath();
	canvas.stroke();

	return true;
}

function curveRectangleDemo() {
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	var x0 = 25.6;
	var y0 = 25.6;
	var rect_width = 204.8;
	var rect_height = 204.8;
	var radius = 102.4;
	var x1, y1;

	x1 = x0 + rect_width;
	y1 = y0 + rect_height;
	if( rect_width/2 < radius ) {
		if( rect_height/2<radius ) {
			canvas.moveTo( x0, (y0+y1)/2 );
			canvas.bezierCurveTo( x0, y0, x0, y0, (x0+x1)/2, y0 );
			canvas.bezierCurveTo( x1, y0, x1, y0, x1, (y0+y1)/2 );
			canvas.bezierCurveTo( x1, y1, x1, y1, (x0+x1)/2, y1 );
			canvas.bezierCurveTo( x0, y1, x0, y1, x0, (y0+y1)/2 );
		}
		else {
			canvas.moveTo( x0, y0+raius );
			canvas.bezierCurveTo( x0, y0, x0, y0, (x0+x1)/2, y0 );
			canvas.bezierCurveTo( x1, y0, x1, y0, x1, y0+radius );
			canvas.lineTo( x1, y1-radius );
			canvas.bezierCurveTo( x1, y1, x1, y1, (x1+x0)/2, y1 );
			canvas.bezierCurveTo( x0, y1, x0, y1, x0, y1-radius );
		}
	}
	else {
		if( rect_height/2<radius ) {
			canvas.moveTo( x0, (y0+y1)/2 );
			canvas.bezierCurveTo( x0, y0, x0, y0, x0+radius, y0 );
			canvas.lineTo( x1-radius, y0 );
			canvas.bezierCurveTo( x1, y0, x1, y0, x1, (y0+y1)/2 );
			canvas.bezierCurveTo( x1, y1, x1, y1, x1-radius, y1 );
			canvas.lineTo( x0+radius, y1 );
			canvas.bezierCurveTo( x0, y1, x0, y1, x0, (y0+y1)/2 );
		}
		else {
			canvas.moveTo( x0, y0+radius );
			canvas.bezierCurveTo( x0, y0, x0, y0, x0+radius, y0 );
			canvas.lineTo( x1-radius, y0 );
			canvas.bezierCurveTo( x1, y0, x1, y0, x1, y0+radius );
			canvas.lineTo( x1, y1-radius );
			canvas.bezierCurveTo( x1, y1, x1, y1, x1-radius, y1 );
			canvas.lineTo( x0+radius, y1 );
			canvas.bezierCurveTo( x0, y1, x0, y1, x0, y1-radius );
		}
	}
	canvas.closePath();
	canvas.fillStyle = "rgb( 128, 128, 255 )";
	canvas.fill(); // no fill_preserve(), so you won't see the border.
	canvas.strokeStyle = "rgb( 255, 0, 0 )";
	canvas.globalAlpha = 0.5;
	canvas.lineWidth = 10;
	canvas.stroke();

	return true;
}

function curveToDemo() {
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	var x=25.6, y=128;
	var x1=102.4, y1=230.4, x2=153.6, y2=25.6, x3=230.4, y3=128.0;

	canvas.moveTo( x, y );
	canvas.bezierCurveTo( x1, y1, x2, y2, x3, y3 );
	canvas.lineWidth = 10;
	canvas.stroke();

	canvas.strokeStyle = "rgb( 255, 51, 51 )";
	canvas.globalAlpha = 0.6;
	canvas.lineWidth = 6;
	canvas.moveTo( x, y ); canvas.lineTo( x1, y1 );
	canvas.moveTo( x2, y2 ); canvas.lineTo( x3, y3 );
	canvas.stroke();

	return true;
}

function rotateDemo() {
	drawingArea.window.clear();

	var canvas = createCairoCanvas();
	canvas.translate( 128, 128 );
	canvas.rotate( 45*Math.PI/180 );
	canvas.scale( 0.9, 0.9 );

	canvas.fillStyle = "rgb(200,0,0)";
	canvas.fillRect( 10, 10, 55, 50 );

	canvas.strokeStyle = "rgb( 0, 200, 0 )";
	canvas.strokeRect( 50, 50, 155, 150 );

	canvas.strokeStyle = "rgb( 0, 0, 255 )";
	canvas.arc( 137.5, 137.5, 100, 0, Math.PI*2, true );
	canvas.stroke();
	return true;
}

//
// routines
//
function createButton( label, handler ) {
	var button = new Gtk.Button( {label: label} );
	button.signal.clicked.connect( handler );
	return button;
}

function createButtonGroup()
{
	var buttonGroup = new Gtk.VBox();
	//var buttonGroup = new Gtk.VButtonBox();
	buttonGroup.pack_start( createButton( "Stroke", function() {
		exposeEvent = strokeDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "Fill", function() {
		exposeEvent = fillDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "4 color", function() {
		exposeEvent = fourColorDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "Path", function() {
		exposeEvent = pathDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "Scale and Transform", function() {
		exposeEvent = scaleAndTransformDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "Arc", function() {
		exposeEvent = arcDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "Clip", function() {
		exposeEvent = clipDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "Curve Rectangle", function() {
		exposeEvent = curveRectangleDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "Curve To", function() {
		exposeEvent = curveToDemo;
		return exposeEvent();
	}), true, true);
	buttonGroup.pack_start( createButton( "Rotate", function() {
		exposeEvent = rotateDemo;
		return exposeEvent();
	} ), true, true);
	return buttonGroup;
}

//
// Events
//
function drawingArea_ExposeEvent() {
	return exposeEvent();
}

//
// Main
//

// Make the program terminate when the window is closed
window.signal.hide.connect(Gtk.main_quit);

drawingArea.signal.expose_event.connect( drawingArea_ExposeEvent );

hbox.pack_start( createButtonGroup(), false, false);
hbox.pack_start( drawingArea, true, true );

vbox.pack_start( hbox, true, true );
vbox.pack_start( status, false, false, 0);

window.add(vbox);
window.show_all();
window.resize( 640, 480 );

// Start the main GTK+ loop and initiate the program
Gtk.main();
關於這個例子,大部分都是從 Cairo網站上的範例搬來的,也幾乎演示了所有的函數,但還是有少數函數與屬性沒有涵蓋到,如 transform、setTransform、clearRect、quadraticCurveTo...等~ 有需要再自己去翻 seed-canvas.c 看吧~


Posted by elleryq at 樂多Roodo! │18:22 │回應(0)引用(0)資訊相關Idea與筆記
樂多分類:網路/3C 共同主題:JavaScript範例 工具:編輯本文
標籤:JavaScript,linux,gtk
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/8345465