texture_rect.nim 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # author: Ethosa
  2. import ../core/sdl2
  3. import ../core/sdl2/gfx
  4. import control
  5. import ../default/enums
  6. import ../default/anchor
  7. import ../default/vector2
  8. import ../default/imagenodes
  9. import ../defaultnodes/canvas
  10. import ../defaultnodes/node
  11. {.used.}
  12. type
  13. TextureRectObj* = object of ControlObj
  14. keep_in*: bool
  15. texture_mode*: TextureMode
  16. texture_anchor*: AnchorRef
  17. texture*: SurfacePtr
  18. TextureRectPtr* = ptr TextureRectObj
  19. proc TextureRect*(name: string, variable: var TextureRectObj): TextureRectPtr =
  20. ## Creates a new TextureRect pointer.
  21. nodepattern(TextureRectObj)
  22. canvaspattern()
  23. variable.rect_size = Vector2(40.0, 40.0)
  24. variable.texture_anchor = Anchor(0.5, 0.5, 0.5, 0.5)
  25. variable.texture_mode = TEXTURE_KEEP_ASPECT_RATIO
  26. variable.texture = nil
  27. variable.keep_in = true
  28. variable.surface = createRGBSurface(
  29. 0, 40, 40, 32, 0xFF000000'u32, 0x00FF0000,
  30. 0x0000FF00, 0x000000FF
  31. )
  32. variable.renderer = variable.surface.createSoftwareRenderer()
  33. proc TextureRect*(variable: var TextureRectObj): TextureRectPtr {.inline.} =
  34. TextureRect("TextureRect", variable)
  35. proc calcRect(pos, size: Vector2Ref, anchor: AnchorRef, w, h: cint): Rect {.inline.} =
  36. ## Calculates rectangle for blit texture.
  37. result.x = pos.x.cint + (size.x*anchor.x1 - w.float*anchor.x2).cint
  38. result.y = pos.y.cint + (size.y*anchor.y1 - h.float*anchor.y2).cint
  39. result.w = w
  40. result.h = h
  41. method draw*(self: TextureRectPtr, surface: SurfacePtr) =
  42. ## Draws node on the surface
  43. {.warning[LockLevel]: off.}
  44. if self.visible and self.surface != nil:
  45. self.resize(self.rect_size.x, self.rect_size.y)
  46. self.calcGlobalPosition()
  47. # -- Draw texture -- #
  48. if self.texture != nil:
  49. let pos = if self.keep_in: Vector2() else: self.global_position
  50. var target = if self.keep_in: self.surface else: surface
  51. case self.texture_mode
  52. of TEXTURE_CROP:
  53. var texture_rect = calcRect(pos, self.rect_size, self.texture_anchor, self.texture.w, self.texture.h)
  54. self.texture.blitSurface(nil, target, texture_rect.addr)
  55. of TEXTURE_FULL_SIZE:
  56. var
  57. w = self.rect_size.x / self.texture.w.float
  58. h = self.rect_size.y / self.texture.h.float
  59. timed = self.texture.rotozoomSurfaceXY(0, w.cdouble, h.cdouble, 1)
  60. texture_rect = calcRect(pos, self.rect_size, self.texture_anchor, timed.w, timed.h)
  61. timed.blitSurface(nil, target, texture_rect.addr)
  62. timed.freeSurface()
  63. timed = nil
  64. of TEXTURE_KEEP_ASPECT_RATIO:
  65. var
  66. w = self.rect_size.x / self.texture.w.float
  67. h = self.rect_size.y / self.texture.h.float
  68. q = if w < h: w else: h
  69. timed = self.texture.rotozoomSurfaceXY(0, q.cdouble, q.cdouble, 1)
  70. texture_rect = calcRect(pos, self.rect_size, self.texture_anchor, timed.w, timed.h)
  71. timed.blitSurface(nil, target, texture_rect.addr)
  72. timed.freeSurface()
  73. timed = nil
  74. # -- Draw surface -- #
  75. var self_rect = rect(
  76. self.global_position.x.cint, self.global_position.y.cint,
  77. self.surface.w, self.surface.h
  78. )
  79. self.surface.blitSurface(nil, surface, self_rect.addr)
  80. if self.pressed:
  81. var x, y: cint
  82. discard getMouseState(x, y)
  83. self.press(x.float, y.float)
  84. method resize*(self: TextureRectPtr, width, height: float) =
  85. self.rect_size = Vector2Ref(x: width, y: height)
  86. var timed_surface = createRGBSurface(
  87. 0, width.cint, height.cint, 32, 0xFF000000'u32, 0x00FF0000,
  88. 0x0000FF00, 0x000000FF
  89. )
  90. sdl2.destroy(self.renderer)
  91. self.surface.blitSurface(nil, timed_surface, nil)
  92. self.surface.freeSurface()
  93. self.surface = nil
  94. self.surface = timed_surface
  95. self.renderer = self.surface.createSoftwareRenderer()