123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- # 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()
|