|
|
|
|
Reply From: |
Zylann |
Apparently not, there is no such thing on the built-in control. However that could be easy to implement in GDScript though, with a custom _draw()
method.
Edit: may this script be useful to you
It should be put on a Control
node.
tool
extends Control
const MODE_STRETCH = 0
const MODE_TILE = 1
export(Texture) var texture = null setget set_texture
export var draw_center = true setget set_draw_center
export(int, "Stretch", "Tile") var slice_mode = MODE_STRETCH setget set_slice_mode
export var left_slice = 0 setget set_left_slice
export var right_slice = 0 setget set_right_slice
export var top_slice = 0 setget set_top_slice
export var bottom_slice = 0 setget set_bottom_slice
func _ready():
pass
func set_texture(tex):
texture = tex
update()
func set_slice_mode(m):
slice_mode = m
update()
func set_draw_center(dc):
draw_center = dc
update()
func set_left_slice(m):
if m < 0:
m = 0
left_slice = m
update()
func set_right_slice(m):
if m < 0:
m = 0
right_slice = m
update()
func set_top_slice(m):
if m < 0:
m = 0
top_slice = m
update()
func set_bottom_slice(m):
if m < 0:
m = 0
bottom_slice = m
update()
func _draw():
if texture == null:
return
var r = get_rect()
var ts = texture.get_size()
var rs = r.size
var ks = rs / ts
var dst_left = left_slice# * ks.x
var dst_right = right_slice# * ks.x
var dst_top = top_slice# * ks.y
var dst_bottom = bottom_slice# * ks.y
if top_slice > 0:
if left_slice > 0:
# Top-left corner
draw_texture_rect_region(texture, \
Rect2(0, 0, dst_left, dst_top), \
Rect2(0, 0, left_slice, top_slice))
if right_slice > 0:
# Top-right corner
draw_texture_rect_region(texture, \
Rect2(rs.x - dst_right, 0, dst_right, dst_top), \
Rect2(ts.x - right_slice, 0, right_slice, top_slice))
# Top side
draw_texture_rect_region_mode(texture, \
Rect2(dst_left, 0, rs.x - dst_left - dst_right, dst_top), \
Rect2(left_slice, 0, ts.x - left_slice - right_slice, top_slice))
if bottom_slice > 0:
if left_slice > 0:
# Bottom-left corner
draw_texture_rect_region(texture, \
Rect2(0, rs.y - dst_bottom, dst_left, dst_bottom), \
Rect2(0, ts.y - bottom_slice, left_slice, bottom_slice))
if right_slice > 0:
# Bottom-right corner
draw_texture_rect_region(texture, \
Rect2(rs.x - dst_right, rs.y - dst_bottom, dst_right, dst_bottom), \
Rect2(ts.x - right_slice, ts.y - bottom_slice, right_slice, bottom_slice))
# Bottom side
draw_texture_rect_region_mode(texture, \
Rect2(dst_left, rs.y - dst_bottom, rs.x - dst_left - dst_right, dst_bottom), \
Rect2(left_slice, ts.y - bottom_slice, ts.x - left_slice - right_slice, bottom_slice))
if left_slice > 0:
# Left side
draw_texture_rect_region_mode(texture, \
Rect2(0, dst_top, dst_left, rs.y - dst_top - dst_bottom), \
Rect2(0, top_slice, left_slice, ts.y - top_slice - bottom_slice))
if right_slice > 0:
# Right side
draw_texture_rect_region_mode(texture, \
Rect2(rs.x - dst_right, dst_top, dst_right, rs.y - dst_top - dst_bottom), \
Rect2(ts.x - right_slice, top_slice, right_slice, ts.y - top_slice - bottom_slice))
if draw_center:
# Center
draw_texture_rect_region_mode(texture, \
Rect2(dst_left, dst_top, rs.x - dst_right - dst_left, rs.y - dst_top - dst_bottom), \
Rect2(left_slice, top_slice, ts.x - right_slice - left_slice, ts.y - top_slice - bottom_slice))
func draw_texture_rect_region_mode(tex, dst_rect, src_rect):
if slice_mode == MODE_STRETCH:
draw_texture_rect_region(tex, dst_rect, src_rect)
else:
draw_texture_rect_region_tiled(tex, dst_rect, src_rect)
func draw_texture_rect_region_tiled(tex, dst_rect, src_rect):
var pos = Vector2(0,0)
var dst_pos = dst_rect.pos
var src_size = src_rect.size
while pos.y + src_size.y < dst_rect.size.y:
while pos.x + src_size.x < dst_rect.size.x:
draw_texture_rect_region(tex, Rect2(dst_pos + pos, src_size), src_rect)
pos.x += src_size.x
pos.x = 0
pos.y += src_size.y
var cropped_src_rect = Rect2( \
src_rect.pos.x, \
src_rect.pos.y, \
src_rect.size.x, \
dst_rect.size.y - pos.y)
while pos.x + src_size.x < dst_rect.size.x:
draw_texture_rect_region(tex, Rect2(dst_pos + pos, cropped_src_rect.size), cropped_src_rect)
pos.x += src_size.x
pos.y = 0
var cropped_src_rect = Rect2(
src_rect.pos.x, \
src_rect.pos.y, \
dst_rect.size.x - pos.x, \
src_rect.size.y)
while pos.y + src_size.y < dst_rect.size.y:
draw_texture_rect_region(tex, Rect2(dst_pos + pos, cropped_src_rect.size), cropped_src_rect)
pos.y += src_size.y
var cropped_src_rect = Rect2(
src_rect.pos.x, \
src_rect.pos.y, \
dst_rect.size.x - pos.x, \
dst_rect.size.y - pos.y)
draw_texture_rect_region(tex, Rect2(dst_pos + pos, cropped_src_rect.size), cropped_src_rect)
Thanks for the response. Ill test this tonight when I get home.
TomShar | 2017-02-20 11:55
@Zylann That works perfectly, only problem is the editor doesn’t show a preview. Is this possible to fix or will this only work at runtime?
TomShar | 2017-02-20 17:10
Strange, it is supposed to show a preview, I put the tool
keyword on top and tested it myself. Do you have errors in the console? Godot 2.1.2?
Zylann | 2017-02-20 18:26
Huh, weird. I closed and re-opened the software and it is working now. Thanks again for this.
TomShar | 2017-02-20 18:33
There does seem to be a lot of draw_texture_rect_region
calls. Should I be concerned about performance issues if I use this a lot/for large areas?
TomShar | 2017-02-20 18:38
If your tiles are very small and the frame is big, there will be more calls yes, but they should be done only once if the frame doesn’t change. You can put a print inside the _draw
function to see how many times it gets called, or use the profiler to see if overall performance is affected.
Also, that looks like a lot of code but that’s because I made it linear to avoid if statements and useless calculations in loops.
Ideally this should be better put in the engine one day if many people request it.
Zylann | 2017-02-20 19:29
Ah, I’m new to the engine. I was expecting the _draw
function to get called each frame for some reason. Obviously, that must only get run when a change is detected?
TomShar | 2017-02-20 20:22
Yes, like resizing the control, changing the texture, or when update()
is called explicitely. Give it a try with a print to see how often it’s called
Zylann | 2017-02-20 20:25
Yeah I did, very interesting. Thanks for all the help.
TomShar | 2017-02-20 20:42