# author: Ethosa import ../core/sdl2 import ../core/sdl2/gfx import control import ../default/enums import ../default/anchor import ../default/vector2 import ../default/imagenodes import ../defaultnodes/canvas import ../defaultnodes/node {.used.} type TextureRectObj* = object of ControlObj keep_in*: bool texture_mode*: TextureMode texture_anchor*: AnchorRef texture*: SurfacePtr TextureRectPtr* = ptr TextureRectObj proc TextureRect*(name: string, variable: var TextureRectObj): TextureRectPtr = ## Creates a new TextureRect pointer. nodepattern(TextureRectObj) canvaspattern() variable.rect_size = Vector2(40.0, 40.0) variable.texture_anchor = Anchor(0.5, 0.5, 0.5, 0.5) variable.texture_mode = TEXTURE_KEEP_ASPECT_RATIO variable.texture = nil variable.keep_in = true variable.surface = createRGBSurface( 0, 40, 40, 32, 0xFF000000'u32, 0x00FF0000, 0x0000FF00, 0x000000FF ) variable.renderer = variable.surface.createSoftwareRenderer() proc TextureRect*(variable: var TextureRectObj): TextureRectPtr {.inline.} = TextureRect("TextureRect", variable) proc calcRect(pos, size: Vector2Ref, anchor: AnchorRef, w, h: cint): Rect {.inline.} = ## Calculates rectangle for blit texture. result.x = pos.x.cint + (size.x*anchor.x1 - w.float*anchor.x2).cint result.y = pos.y.cint + (size.y*anchor.y1 - h.float*anchor.y2).cint result.w = w result.h = h method draw*(self: TextureRectPtr, surface: SurfacePtr) = ## Draws node on the surface {.warning[LockLevel]: off.} if self.visible and self.surface != nil: self.resize(self.rect_size.x, self.rect_size.y) self.calcGlobalPosition() # -- Draw texture -- # if self.texture != nil: let pos = if self.keep_in: Vector2() else: self.global_position var target = if self.keep_in: self.surface else: surface case self.texture_mode of TEXTURE_CROP: var texture_rect = calcRect(pos, self.rect_size, self.texture_anchor, self.texture.w, self.texture.h) self.texture.blitSurface(nil, target, texture_rect.addr) of TEXTURE_FULL_SIZE: var w = self.rect_size.x / self.texture.w.float h = self.rect_size.y / self.texture.h.float timed = self.texture.rotozoomSurfaceXY(0, w.cdouble, h.cdouble, 1) texture_rect = calcRect(pos, self.rect_size, self.texture_anchor, timed.w, timed.h) timed.blitSurface(nil, target, texture_rect.addr) timed.freeSurface() timed = nil of TEXTURE_KEEP_ASPECT_RATIO: var w = self.rect_size.x / self.texture.w.float h = self.rect_size.y / self.texture.h.float q = if w < h: w else: h timed = self.texture.rotozoomSurfaceXY(0, q.cdouble, q.cdouble, 1) texture_rect = calcRect(pos, self.rect_size, self.texture_anchor, timed.w, timed.h) timed.blitSurface(nil, target, texture_rect.addr) timed.freeSurface() timed = nil # -- Draw surface -- # var self_rect = rect( self.global_position.x.cint, self.global_position.y.cint, self.surface.w, self.surface.h ) self.surface.blitSurface(nil, surface, self_rect.addr) if self.pressed: var x, y: cint discard getMouseState(x, y) self.press(x.float, y.float) method resize*(self: TextureRectPtr, width, height: float) = self.rect_size = Vector2Ref(x: width, y: height) var timed_surface = createRGBSurface( 0, width.cint, height.cint, 32, 0xFF000000'u32, 0x00FF0000, 0x0000FF00, 0x000000FF ) sdl2.destroy(self.renderer) self.surface.blitSurface(nil, timed_surface, nil) self.surface.freeSurface() self.surface = nil self.surface = timed_surface self.renderer = self.surface.createSoftwareRenderer()