<commit_before>/*! Graphics2D
 * 
 *  Author: Keyten aka <NAME>
 *
 *  10.09.12 / 23:11
 */

var Graphics2D = (function(window, undefined){

	var Context,

		// shapes
		Shape, Rect, Circle, Path,

		emptyFunc = function(){};


	Context = function(canvas){

		this.context   = canvas.getContext('2d');
		this.canvas    = canvas;
		this.elements  = [];
		this.listeners = {};

	}

	Context.prototype = {

		// shapes
		rect : function(x,y,w,h,fill,stroke){
			return this.push( new Rect(x,y,w,h,fill,stroke,this) );
		},

		circle : function(x,y,r,fill,stroke){
			return this.push( new Circle(x,y,r,fill,stroke,this) );
		},

		path : function(path,x,y,closed,fill,stroke){
			return this.push( new Path(path,x,y,closed,fill,stroke,this) );
		},

		image : function(image,x,y,w,h){
			return this.push( new Img(image,x,y,w,h,this) );
		},

		text : function(text,font,x,y,fill,stroke){
			return this.push( new Text(text,font,x,y,fill,stroke,this) );
		},

		textblock : function(text,font,x,y,w,fill,stroke){
			return this.push( new TextBlock(text,font,x,y,w,fill,stroke,this) );
		},


		push : function(element){
			this.elements.push(element);
			if( element.draw )
				element.draw(this.context);
			return element;
		},


		// methods
		update : function(){

			var ctx = this.context;
			ctx.clearRect( 0, 0, this.canvas.width, this.canvas.height );
			this.elements.forEach(function(object){

				object.draw(ctx);

			});
			this.fire('update');

		},

		getObjectInPoint : function(x,y){
			var element = null,
				elements = this.elements;
			
			var i = elements.length;
			while(i--){
				if( elements[i].isPointIn && elements[i].isPointIn( distance(x), distance(y)) ){
					element = elements[i];
					return elements[i];
					break;
				}
			}
			return element;
		},

		// events
		_checkListeners : emptyFunc,
		
		on : emptyFunc,

		fire : emptyFunc

	};


	/* Shape
		abstract class for inheriting shapes */

	Shape = Class({

		initialize : function(){
			this._attr = extend(new Shape.attributes, this.constructor.defaults || {});
			this.data = {};
			this.listeners = {};
		},


		_set : function(name, value, obj){
			if(value == null) return obj[name];
			obj[name] = value;
			this.context.update();
			return this;
		},

		property : function(name, value){
			return this._set(name, value, this._attr)
		},
		
		style : function(name, value){
			return this._set(name, value, this._attr.style)
		},


		fill : function(color){
			return this.style('fillStyle', color);
		},
		
		opacity : function(opacity){
			return this.style('globalAlpha', opacity);
		},
		
		composite : function(composite){
			return this.style('globalCompositeOperation', composite);
		},
		
		stroke : function(str){
			var s = this._attr.style;
			if(str == null)
				return {
					color : s.strokeStyle,
					width : s.lineWidth,
					cap   : s.lineCap,
					join  : s.lineJoin,
					dash  : s._lineDash
				};
			extend(s, stroke(str));
			this.context.update();
			return this;
		},

		mask : function(shape){
			return this.property('mask', shape);
		},
		
		hide : function(){
			return this.property('visible', false);
		},
		
		show : function(){
			return this.property('visible', true);
		},

		cursor : function(cur){
			var cnv = this.context.canvas,
				stg = this.context,
				elm = this,
				old = cnv.style.cursor;
			cnv.addEventListener('mousemove', function(e){ // заменить на this.hover(fn1, fn2);
				var obj = stg.getObjectInPoint(e.clientX - cnv.offsetLeft, e.clientY - cnv.offsetTop);
				if( obj )
					cnv.style.cursor = cur;
				else
					cnv.style.cursor = old;
			}, false);
		},

		draw : function(ctx){
			var a = this._attr;

			if(!a.visible) return;
			style(ctx, a.style);
//			if(a.gradient && a.gradient.redraw){
//				ctx.fillStyle = createGradient(ctx, a.gradient, this.bounds());
//			}
			this.processPath(ctx);
			if(a.style.fillStyle) ctx.fill();
			if(a.style.strokeStyle) ctx.stroke();
			ctx.restore();
		},

		isPointIn : function(x,y){
			var ctx = this.context.context;
			this.processPath( ctx );
			return ctx.isPointInPath( x, y );
		}
<commit_msg>Added events<commit_after>/*! Graphics2D
 * 
 *  Author: Keyten aka <NAME>
 *
 *  10.09.12 / 23:11
 */

var Graphics2D = (function(window, undefined){

	var Context,

		// shapes
		Shape, Rect, Circle, Path,

		emptyFunc = function(){};


	Context = function(canvas){

		this.context   = canvas.getContext('2d');
		this.canvas    = canvas;
		this.elements  = [];
		this.listeners = {};

	}

	Context.prototype = {

		// shapes
		rect : function(x,y,w,h,fill,stroke){
			return this.push( new Rect(x,y,w,h,fill,stroke,this) );
		},

		circle : function(x,y,r,fill,stroke){
			return this.push( new Circle(x,y,r,fill,stroke,this) );
		},

		path : function(path,x,y,closed,fill,stroke){
			return this.push( new Path(path,x,y,closed,fill,stroke,this) );
		},

		image : function(image,x,y,w,h){
			return this.push( new Img(image,x,y,w,h,this) );
		},

		text : function(text,font,x,y,fill,stroke){
			return this.push( new Text(text,font,x,y,fill,stroke,this) );
		},

		textblock : function(text,font,x,y,w,fill,stroke){
			return this.push( new TextBlock(text,font,x,y,w,fill,stroke,this) );
		},


		push : function(element){
			this.elements.push(element);
			if( element.draw )
				element.draw(this.context);
			return element;
		},


		// methods
		update : function(){

			var ctx = this.context;
			ctx.clearRect( 0, 0, this.canvas.width, this.canvas.height );
			this.elements.forEach(function(object){

				object.draw(ctx);

			});
			this.fire('update');

		},

		getObjectInPoint : function(x,y){
			var element = null,
				elements = this.elements;
			
			var i = elements.length;
			while(i--){
				if( elements[i].isPointIn && elements[i].isPointIn( distance(x), distance(y)) ){
					element = elements[i];
					return elements[i];
					break;
				}
			}
			return element;
		},

		// events
		_setupped : false,
		hoverElement : null,
		focusElement : null,
		_checkListeners : function(){

			if(this._setupped) return;
			this._setupped = true;

			var element = this.canvas,
				listeners = this.listeners,
				context = this;

			[ 'click', 'dblclick', 'mousedown',
			  'mouseup', 'mousemove', 'mouseover', 'mouseout' ].forEach(function(event){

				element.addEventListener(event, function(e){

					var object = context.getObjectInPoint(
							e.contextX = e.clientX - element.offsetLeft,
							e.contextY = e.clientY - element.offsetTop
						);

					if(object && object.fire)
						e.targetObject = object,
						object.fire(event, e);

					context.fire(event, e);

				});

			});

			[{ evt:'mousemove', in:'mouseover', out:'mouseout' }, { evt:'mousedown', in:'focus', out:'blur' }].forEach(function(obj, i){

				var id = '_evt' + i;

				context.on(obj.evt, function(e){

					var targ = e.targetObject;
					if(context[id] != targ && context[id])
						context[id].fire(obj.out, e)[id] = false;

					if(targ && !targ[id])
						targ.fire(obj.in, e)[id] = true;

					context[id] = targ;

				});

			});


		},
		
		on : function(evt, fn){

			this._checkListeners();
			(this.listeners[ evt ] || (this.listeners[ evt ] = [])).push(fn);
			return this;

		},

		fire : function(evt, data){

			var listeners = this.listeners[ evt ];
			if(!listeners) return this;

			var object = this.canvas;
			listeners.forEach(function(func){
				func.call(object, data);
			});
			return this;
		
		}

	};


	/* Shape
		abstract class for inheriting shapes */

	Shape = Class({

		initialize : function(){
			this._attr = extend(new Shape.attributes, this.constructor.defaults || {});
			this.data = {};
			this.listeners = {};
		},


		_set : function(name, value, obj){
			if(value == null) return obj[name];
			obj[name] = value;
			this.context.update();
			return this;
		},

		property : function(name, value){
			return this._set(name, value, this._attr)
		},
		
		style : function(name, value){
			return this._set(name, value, this._attr.style)
		},


		fill : function(color){
			return this.style('fillStyle', color);
		},
		
		opacity : function(opacity){
			return this.style('globalAlpha', opacity);
		},
		
		composite : function(composite){
			return this.style('globalCompositeOperation', composite);
		},
		
		stroke : function(str){
			var s = this._attr.style;
			if(str == null)
				return {
					color : s.strokeStyle,
					width : s.lineWidth,
					cap   : s.lineCap,
					join  : s.lineJoin,
					dash  : s._lineDash
				};
			extend(s, stroke(str));
			this.context.update();
			return this;
		},

		mask : function(shape){
			return this.property('mask', shape);
		},
		
		hide : function(){
			return this.property('visible', false);
		},
		
		show : function(){
			return this.property('visible', true);
		},

		cursor : function(cur){
			var cnv = this.context.canvas,
				old = cnv.style.cursor;
			return this.on('mouseover', function(){
				cnv.style.cursor = cur
			}).on('mouseout', function(){
				cnv.style.cursor = old;
			});
		},

		on : function(event,fn){
			this.context._checkListeners();
			(this.listeners[ event ] || (this.listeners[ event ] = [])).push(fn);
			return this;
		},

		fire : function(event, data){
			(this.listeners[ event ] || []).forEach(function(func){
				func.call(this, data);
			}.bind(this));
			return this;
		},

		draw : function(ctx){
			var a = this._attr;

			if(!a.visible) return;
			style(ctx, a.style);
//			if(a.gradient && a.gradient.redraw){
//				ctx.fillStyle = createGradient(ctx, a.gradient, this.bounds());
//			}
			this.processPath(ctx);
			if(a.style.fillStyle) ctx.fill();
			if(a.style.strokeStyle) ctx.stroke();
			ctx.restore();
		},

		isPointIn : function(x,y){
			var ctx = this.context.context;
			this.processPath( ctx );
			return ctx.isPointInPath( x, y );
		}

{'fraction_non_alphanumeric': 0.16995199673169237, 'fraction_numerical': 0.0032683076294556224, 'mean_word_length': 3.042939719240297, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1298194', 'n_tokens_mistral': 4194, 'n_tokens_neox': 3396, 'n_words': 662}