예제 #1
0
static void
_draw_line(const Termpty *ty, unsigned int *pixels,
           const Termcell *cells, int length, unsigned int *colors)
{
   int x;

   for (x = 0 ; x < length; x++)
     {
        _draw_cell(ty, pixels + x, cells + x, colors);
     }
}
예제 #2
0
void TileMapEditor::_canvas_draw() {

	if (!node)
		return;

	Matrix32 cell_xf = node->get_cell_transform();

	Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
	Matrix32 xform_inv = xform.affine_inverse();


	Size2 screen_size=canvas_item_editor->get_size();
	{
		Rect2 aabb;
		aabb.pos=node->world_to_map(xform_inv.xform(Vector2()));
		aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(0,screen_size.height))));
		aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(screen_size.width,0))));
		aabb.expand_to(node->world_to_map(xform_inv.xform(screen_size)));
		Rect2i si=aabb.grow(1.0);

		if (node->get_half_offset()!=TileMap::HALF_OFFSET_X) {

			int max_lines=2000; //avoid crash if size too smal

			for (int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) {

				Vector2 from = xform.xform(node->map_to_world(Vector2(i,si.pos.y)));
				Vector2 to = xform.xform(node->map_to_world(Vector2(i,si.pos.y+si.size.y+1)));

				Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
				canvas_item_editor->draw_line(from,to,col,1);
				if (max_lines--==0)
					break;
			}
		} else {

			int max_lines=10000; //avoid crash if size too smal

			for (int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) {

				for (int j=(si.pos.y)-1;j<=(si.pos.y+si.size.y);j++) {

					Vector2 ofs;
					if (ABS(j)&1) {
						ofs=cell_xf[0]*0.5;
					}

					Vector2 from = xform.xform(node->map_to_world(Vector2(i,j),true)+ofs);
					Vector2 to = xform.xform(node->map_to_world(Vector2(i,j+1),true)+ofs);
					Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
					canvas_item_editor->draw_line(from,to,col,1);

					if (max_lines--==0)
						break;

				}

			}
		}

		int max_lines=10000; //avoid crash if size too smal

		if (node->get_half_offset()!=TileMap::HALF_OFFSET_Y) {

			for (int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) {

				Vector2 from = xform.xform(node->map_to_world(Vector2(si.pos.x,i)));
				Vector2 to = xform.xform(node->map_to_world(Vector2(si.pos.x+si.size.x+1,i)));

				Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
				canvas_item_editor->draw_line(from,to,col,1);

				if (max_lines--==0)
					break;

			}
		} else {


			for (int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) {

				for (int j=(si.pos.x)-1;j<=(si.pos.x+si.size.x);j++) {

					Vector2 ofs;
					if (ABS(j)&1) {
						ofs=cell_xf[1]*0.5;
					}

					Vector2 from = xform.xform(node->map_to_world(Vector2(j,i),true)+ofs);
					Vector2 to = xform.xform(node->map_to_world(Vector2(j+1,i),true)+ofs);
					Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
					canvas_item_editor->draw_line(from,to,col,1);

					if (max_lines--==0)
						break;

				}
			}
		}
	}

	if (selection_active) {

		Vector<Vector2> points;
		points.push_back( xform.xform( node->map_to_world(( rectangle.pos ) )));
		points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(rectangle.size.x+1,0)) ) ));
		points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(rectangle.size.x+1,rectangle.size.y+1)) ) ));
		points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(0,rectangle.size.y+1)) ) ));

		canvas_item_editor->draw_colored_polygon(points, Color(0.2,0.8,1,0.4));
	}

	if (mouse_over){

		Vector2 endpoints[4]={
			node->map_to_world(over_tile, true),
			node->map_to_world((over_tile+Point2(1,0)), true),
			node->map_to_world((over_tile+Point2(1,1)), true),
			node->map_to_world((over_tile+Point2(0,1)), true)
		};

		for (int i=0;i<4;i++) {
			if (node->get_half_offset()==TileMap::HALF_OFFSET_X && ABS(over_tile.y)&1)
				endpoints[i]+=cell_xf[0]*0.5;
			if (node->get_half_offset()==TileMap::HALF_OFFSET_Y && ABS(over_tile.x)&1)
				endpoints[i]+=cell_xf[1]*0.5;
			endpoints[i]=xform.xform(endpoints[i]);
		}
		Color col;
		if (node->get_cell(over_tile.x,over_tile.y)!=TileMap::INVALID_CELL)
			col=Color(0.2,0.8,1.0,0.8);
		else
			col=Color(1.0,0.4,0.2,0.8);

		for (int i=0;i<4;i++)
			canvas_item_editor->draw_line(endpoints[i],endpoints[(i+1)%4],col,2);


		if (tool==TOOL_SELECTING || tool==TOOL_PICKING || tool==TOOL_BUCKET) {

			return;
		}

		if (tool==TOOL_LINE_PAINT) {

			if (paint_undo.empty())
				return;

			int id = get_selected_tile();

			if (id==TileMap::INVALID_CELL)
				return;

			for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

				_draw_cell(id, E->key(), flip_h, flip_v, transpose, xform);
			}

		} else if (tool==TOOL_RECTANGLE_PAINT) {

			int id = get_selected_tile();

			if (id==TileMap::INVALID_CELL)
				return;

			for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) {
				for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) {

					_draw_cell(id, Point2i(j, i), flip_h, flip_v, transpose, xform);
				}
			}
		} else if (tool==TOOL_DUPLICATING) {

			if (copydata.empty())
				return;

			Ref<TileSet> ts = node->get_tileset();

			if (ts.is_null())
				return;

			Point2 ofs = over_tile-rectangle.pos;

			for (List<TileData>::Element *E=copydata.front();E;E=E->next()) {

				if (!ts->has_tile(E->get().cell))
					continue;

				TileData tcd = E->get();

				_draw_cell(tcd.cell, tcd.pos+ofs, tcd.flip_h, tcd.flip_v, tcd.transpose, xform);
			}

			Rect2i duplicate=rectangle;
			duplicate.pos=over_tile;

			Vector<Vector2> points;
			points.push_back( xform.xform( node->map_to_world(duplicate.pos ) ));
			points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,0)) ) ));
			points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1))) ));
			points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(0,duplicate.size.y+1))) ));

			canvas_item_editor->draw_colored_polygon(points, Color(0.2,1.0,0.8,0.2));

		} else {

			int st = get_selected_tile();

			if (st==TileMap::INVALID_CELL)
				return;

			_draw_cell(st, over_tile, flip_h, flip_v, transpose, xform);
		}
	}
}