Explorar o código

add GradientDrawable :eyes:

Ethosa %!s(int64=4) %!d(string=hai) anos
pai
achega
a041418720

+ 25 - 24
README.md

@@ -59,30 +59,30 @@
 
 ## Now available
 This section contains links to documentation for all nodes.
-|Core            |Default nodes        |Control nodes         |2D Nodes            |3D Nodes            |Graphics    |
-|:--:            |:--:                 |:--:                  |  :--:              |:--:                |:--:        |
-|[Anchor][]      |[Node][]             |[Control][]           |[Node2D][]          |[Node3D][]          |[Drawable][]|
-|[Color][]       |[Canvas][]           |[ColorRect][]         |[Sprite][]          |[GeometryInstance][]|            |
-|[Font][]        |[Scene][]            |[TextureRect][]       |[AnimatedSprite][]  |                    |            |
-|[Enums][]       |[AudioStreamPlayer][]|[Label][]             |[YSort][]           |                    |            |
-|[Exceptions][]  |[AnimationPlayer][]  |[Button][]            |[CollisionShape2D][]|                    |            |
-|[Image][]       |                     |[EditText][]          |[Camera2D][]        |                    |            |
-|[Input][]       |                     |[Box][]               |                    |                    |            |
-|[Rect2][]       |                     |[HBox][]              |                    |                    |            |
-|[Vector2][]     |                     |[VBox][]              |                    |                    |            |
-|[Circle2][]     |                     |[GridBox][]           |                    |                    |            |
-|[Polygon2][]    |                     |[Scroll][]            |                    |                    |            |
-|[AudioStream][] |                     |[ProgressBar][]       |                    |                    |            |
-|[Animation][]   |                     |[Slider][]            |                    |                    |            |
-|[Vector3][]     |                     |[VSlider][]           |                    |                    |            |
-|[SceneBuilder][]|                     |[Popup][]             |                    |                    |            |
-|[StyleSheet][]  |                     |[TextureButton][]     |                    |                    |            |
-|                |                     |[TextureProgressBar][]|                    |                    |            |
-|                |                     |[Counter][]           |                    |                    |            |
-|                |                     |[Switch][]            |                    |                    |            |
-|                |                     |[SubWindow][]         |                    |                    |            |
-|                |                     |[LineEdit][]          |                    |                    |            |
-|                |                     |[CheckBox][]          |                    |                    |            |
+|Core            |Default nodes        |Control nodes         |2D Nodes            |3D Nodes            |Graphics            |
+|:--:            |:--:                 |:--:                  |  :--:              |:--:                |:--:                |
+|[Anchor][]      |[Node][]             |[Control][]           |[Node2D][]          |[Node3D][]          |[Drawable][]        |
+|[Color][]       |[Canvas][]           |[ColorRect][]         |[Sprite][]          |[GeometryInstance][]|[GradientDrawable][]|
+|[Font][]        |[Scene][]            |[TextureRect][]       |[AnimatedSprite][]  |                    |                    |
+|[Enums][]       |[AudioStreamPlayer][]|[Label][]             |[YSort][]           |                    |                    |
+|[Exceptions][]  |[AnimationPlayer][]  |[Button][]            |[CollisionShape2D][]|                    |                    |
+|[Image][]       |                     |[EditText][]          |[Camera2D][]        |                    |                    |
+|[Input][]       |                     |[Box][]               |                    |                    |                    |
+|[Rect2][]       |                     |[HBox][]              |                    |                    |                    |
+|[Vector2][]     |                     |[VBox][]              |                    |                    |                    |
+|[Circle2][]     |                     |[GridBox][]           |                    |                    |                    |
+|[Polygon2][]    |                     |[Scroll][]            |                    |                    |                    |
+|[AudioStream][] |                     |[ProgressBar][]       |                    |                    |                    |
+|[Animation][]   |                     |[Slider][]            |                    |                    |                    |
+|[Vector3][]     |                     |[VSlider][]           |                    |                    |                    |
+|[SceneBuilder][]|                     |[Popup][]             |                    |                    |                    |
+|[StyleSheet][]  |                     |[TextureButton][]     |                    |                    |                    |
+|                |                     |[TextureProgressBar][]|                    |                    |                    |
+|                |                     |[Counter][]           |                    |                    |                    |
+|                |                     |[Switch][]            |                    |                    |                    |
+|                |                     |[SubWindow][]         |                    |                    |                    |
+|                |                     |[LineEdit][]          |                    |                    |                    |
+|                |                     |[CheckBox][]          |                    |                    |                    |
 
 
 
@@ -188,6 +188,7 @@ Use the [`Nim compiler user guide`](https://nim-lang.org/docs/nimc.html#dynlibov
 [GeometryInstance]:https://ethosa.github.io/nodesnim/nodesnim/nodes3d/geometry_instance.html
 
 [Drawable]:https://ethosa.github.io/nodesnim/nodesnim/graphics/drawable.html
+[GradientDrawable]:https://ethosa.github.io/nodesnim/nodesnim/graphics/gradient_drawable.html
 
 [Examples]:https://github.com/Ethosa/nodesnim/blob/master/examples
 [Wiki]:https://github.com/Ethosa/nodesnim/wiki

+ 6 - 3
src/nodesnim.nim

@@ -4,9 +4,8 @@ when defined(debug):
   var console_logger = newConsoleLogger(fmtStr="[$time]::$levelname - ")
   addHandler(console_logger)
 
-  when not defined(android):
-    var file_logger = newFileLogger("logs.log", fmtStr="[$date at $time]::$levelname - ")
-    addHandler(file_logger)
+  var file_logger = newFileLogger("logs.log", fmtStr="[$date at $time]::$levelname - ")
+  addHandler(file_logger)
 
   info("Compiled in debug mode.")
 
@@ -33,3 +32,7 @@ export
   # Nodes
   core, nodes, graphics,
   nodescontrol, nodes2d, nodes3d
+
+when defined(debug):
+  if standard_font.isNil():
+    error("standard_font not loaded!")

+ 9 - 0
src/nodesnim/core/font.nim

@@ -12,6 +12,9 @@ import
   nodes_os,
   unicode
 
+when defined(debug):
+  import logging
+
 
 type
   StyleUnicode* = ref object
@@ -182,6 +185,12 @@ proc getCaretPos*(text: StyleText, pos: uint32): tuple[a: Vector2Ref, b: uint16]
     result[0].y -= text.spacing
 
 proc render*(text: StyleText, size: Vector2Ref, anchor: AnchorRef) =
+  when defined(debug):
+    if text.font.isNil():
+      error("Font is not loaded!")
+      text.rendered = true
+      return
+
   if not text.font.isNil() and $text != "":
     var
       lines = text.splitLines()

+ 3 - 2
src/nodesnim/graphics.nim

@@ -1,5 +1,6 @@
 import
-  graphics/drawable
+  graphics/drawable,
+  graphics/gradient_drawable
 
 export
-  drawable
+  drawable, gradient_drawable

+ 37 - 34
src/nodesnim/graphics/drawable.nim

@@ -14,26 +14,26 @@ import
 
 
 type
-  DrawableObj* = object
-    shadow: bool
-    border_width: float
-    border_detail_lefttop: int
-    border_detail_righttop: int
-    border_detail_leftbottom: int
-    border_detail_rightbottom: int
-    border_radius_lefttop: float
-    border_radius_righttop: float
-    border_radius_leftbottom: float
-    border_radius_rightbottom: float
-    shadow_offset: Vector2Ref
-    border_color: ColorRef
-    background_color: ColorRef
+  DrawableObj* = object of RootObj
+    shadow*: bool
+    border_width*: float
+    border_detail_lefttop*: int
+    border_detail_righttop*: int
+    border_detail_leftbottom*: int
+    border_detail_rightbottom*: int
+    border_radius_lefttop*: float
+    border_radius_righttop*: float
+    border_radius_leftbottom*: float
+    border_radius_rightbottom*: float
+    shadow_offset*: Vector2Ref
+    border_color*: ColorRef
+    background_color*: ColorRef
     texture*: GlTextureObj
   DrawableRef* = ref DrawableObj
 
 
-proc Drawable*: DrawableRef =
-  DrawableRef(
+template drawablepattern*(`type`: untyped): untyped =
+  result = `type`(
     texture: GlTextureObj(), border_width: 0,
     border_detail_lefttop: 20,
     border_detail_righttop: 20,
@@ -48,12 +48,15 @@ proc Drawable*: DrawableRef =
     shadow_offset: Vector2(0, 0), shadow: false
   )
 
+proc Drawable*: DrawableRef =
+  drawablepattern(DrawableRef)
+
 let shadow_color: ColorRef = Color(0f, 0f, 0f, 0.5f)
 
 
-template vd = discard
+template vd* = discard
 
-template recalc =
+template recalc* =
   # left top
   var t = self.border_radius_lefttop
   vertex.add(Vector2(x, y - t))
@@ -91,7 +94,7 @@ template recalc =
   vertex.add(Vector2(x, y - height + t))
 
 
-template draw_template(drawtype, color, function, secondfunc: untyped): untyped =
+template draw_template*(drawtype, color, function, secondfunc: untyped): untyped =
   glColor4f(`color`.r, `color`.g, `color`.b, `color`.a)
   `function`
   glBegin(`drawtype`)
@@ -102,7 +105,7 @@ template draw_template(drawtype, color, function, secondfunc: untyped): untyped
   glEnd()
   `secondfunc`
 
-template draw_texture_template(drawtype, color, function, secondfunc: untyped): untyped =
+template draw_texture_template*(drawtype, color, function, secondfunc: untyped): untyped =
   glEnable(GL_TEXTURE_2D)
   glBindTexture(GL_TEXTURE_2D, self.texture.texture)
   glColor4f(`color`.r, `color`.g, `color`.b, `color`.a)
@@ -118,11 +121,11 @@ template draw_texture_template(drawtype, color, function, secondfunc: untyped):
   glDisable(GL_TEXTURE_2D)
 
 
-proc enableShadow*(self: DrawableRef, val: bool) =
+method enableShadow*(self: DrawableRef, val: bool) {.base.} =
   ## Enables shadow, when `val` is true.
   self.shadow = val
 
-proc draw*(self: DrawableRef, x1, y1, width, height: float) =
+method draw*(self: DrawableRef, x1, y1, width, height: float) {.base.} =
   var
     vertex: seq[Vector2Ref] = @[]
     x = x1 + self.shadow_offset.x
@@ -148,11 +151,11 @@ proc draw*(self: DrawableRef, x1, y1, width, height: float) =
     draw_template(GL_LINE_LOOP, self.border_color, glLineWidth(self.border_width), glLineWidth(1))
 
 
-proc getColor*(self: DrawableRef): ColorRef =
+method getColor*(self: DrawableRef): ColorRef {.base.} =
   ## Returns background color.
   self.background_color
 
-proc loadTexture*(self: DrawableRef, path: string) =
+method loadTexture*(self: DrawableRef, path: string) {.base.} =
   ## Loads texture from the file.
   ##
   ## Arguments:
@@ -160,19 +163,19 @@ proc loadTexture*(self: DrawableRef, path: string) =
   self.texture = load(path)
   self.background_color = Color(1f, 1f, 1f, 1f)
 
-proc setBorderColor*(self: DrawableRef, color: ColorRef) =
+method setBorderColor*(self: DrawableRef, color: ColorRef) {.base.} =
   ## Changes border color.
   self.border_color = color
 
-proc setBorderWidth*(self: DrawableRef, width: float) =
+method setBorderWidth*(self: DrawableRef, width: float) {.base.} =
   ## Changes border width.
   self.border_width = width
 
-proc setColor*(self: DrawableRef, color: ColorRef) =
+method setColor*(self: DrawableRef, color: ColorRef) {.base.} =
   ## Changes background color.
   self.background_color = color
 
-proc setCornerRadius*(self: DrawableRef, radius: float) =
+method setCornerRadius*(self: DrawableRef, radius: float) {.base.} =
   ## Changes corner radius.
   ##
   ## Arguments:
@@ -182,7 +185,7 @@ proc setCornerRadius*(self: DrawableRef, radius: float) =
   self.border_radius_leftbottom = radius
   self.border_radius_rightbottom = radius
 
-proc setCornerRadius*(self: DrawableRef, r1, r2, r3, r4: float) =
+method setCornerRadius*(self: DrawableRef, r1, r2, r3, r4: float) {.base.} =
   ## Changes corner radius.
   ##
   ## Arguments:
@@ -195,7 +198,7 @@ proc setCornerRadius*(self: DrawableRef, r1, r2, r3, r4: float) =
   self.border_radius_rightbottom = r3
   self.border_radius_leftbottom = r4
 
-proc setCornerDetail*(self: DrawableRef, detail: int) =
+method setCornerDetail*(self: DrawableRef, detail: int) {.base.} =
   ## Changes corner detail.
   ##
   ## Arguments:
@@ -205,7 +208,7 @@ proc setCornerDetail*(self: DrawableRef, detail: int) =
   self.border_detail_leftbottom = detail
   self.border_detail_rightbottom = detail
 
-proc setCornerDetail*(self: DrawableRef, d1, d2, d3, d4: int) =
+method setCornerDetail*(self: DrawableRef, d1, d2, d3, d4: int) {.base.} =
   ## Changes corner detail.
   ##
   ## Arguments:
@@ -218,16 +221,16 @@ proc setCornerDetail*(self: DrawableRef, d1, d2, d3, d4: int) =
   self.border_detail_leftbottom = d4
   self.border_detail_rightbottom = d3
 
-proc setTexture*(self: DrawableRef, texture: GlTextureObj) =
+method setTexture*(self: DrawableRef, texture: GlTextureObj) {.base.} =
   ## Changes drawable texture.
   self.texture = texture
   self.background_color = Color(1f, 1f, 1f, 1f)
 
-proc setShadowOffset*(self: DrawableRef, offset: Vector2Ref) =
+method setShadowOffset*(self: DrawableRef, offset: Vector2Ref) {.base.} =
   ## Changes shadow offset.
   self.shadow_offset = offset
 
-proc setStyle*(self: DrawableRef, s: StyleSheetRef) =
+method setStyle*(self: DrawableRef, s: StyleSheetRef) {.base.} =
   ## Sets a new stylesheet.
   for i in s.dict:
     var matches: array[20, string]

+ 79 - 0
src/nodesnim/graphics/gradient_drawable.nim

@@ -0,0 +1,79 @@
+# author: Ethosa
+import
+  ../thirdparty/opengl,
+
+  ../core/color,
+  ../core/stylesheet,
+  ../core/image,
+  ../core/vector2,
+
+  drawable,
+  math
+
+type
+  GradientDrawableObj* = object of DrawableObj
+    corners*: tuple[p0, p1, p2, p3: ColorRef]
+  GradientDrawableRef* = ref GradientDrawableObj
+
+
+proc GradientDrawable*: GradientDrawableRef =
+  drawablepattern(GradientDrawableRef)
+  result.corners = (Color(1f, 1f, 1f, 1.0),
+                    Color(1f, 1f, 1f, 1.0),
+                    Color(1f, 1f, 1f, 1.0),
+                    Color(1f, 1f, 1f, 1.0))
+
+let shadow_color: ColorRef = Color(0f, 0f, 0f, 0.5f)
+
+
+template draw_template*(drawtype, color, function, secondfunc: untyped, is_gradient: bool = true): untyped =
+  glColor4f(`color`.r, `color`.g, `color`.b, `color`.a)
+  `function`
+  glBegin(`drawtype`)
+
+  if is_gradient:
+    for i in 0..vertex.high:
+      let tmp = i/vertex.len()
+      if tmp < 0.25:
+        glColor4f(self.corners[0].r, self.corners[0].g, self.corners[0].b, self.corners[0].a)
+      elif tmp < 0.5:
+        glColor4f(self.corners[1].r, self.corners[1].g, self.corners[1].b, self.corners[1].a)
+      elif tmp < 0.75:
+        glColor4f(self.corners[2].r, self.corners[2].g, self.corners[2].b, self.corners[2].a)
+      else:
+        glColor4f(self.corners[3].r, self.corners[3].g, self.corners[3].b, self.corners[3].a)
+      glVertex2f(vertex[i].x, vertex[i].y)
+  else:
+    for i in vertex:
+      glVertex2f(i.x, i.y)
+
+  glEnd()
+  `secondfunc`
+
+method draw*(self: GradientDrawableRef, x1, y1, width, height: float) =
+  var
+    vertex: seq[Vector2Ref] = @[]
+    x = x1 + self.shadow_offset.x
+    y = y1 - self.shadow_offset.y
+
+  if self.shadow:
+    recalc()
+    if self.texture.texture > 0'u32:
+      draw_texture_template(GL_POLYGON, shadow_color, vd(), vd())
+    else:
+      draw_template(GL_POLYGON, shadow_color, vd(), vd(), false)
+
+  vertex = @[]
+  x = x1
+  y = y1
+  recalc()
+
+  if self.texture.texture > 0'u32:
+    draw_texture_template(GL_POLYGON, self.background_color, vd(), vd())
+  else:
+    draw_template(GL_POLYGON, self.background_color, vd(), vd())
+  if self.border_width > 0f:
+    draw_template(GL_LINE_LOOP, self.border_color, glLineWidth(self.border_width), glLineWidth(1), false)
+
+method setCornerColors*(self: GradientDrawableRef, corners: tuple[p0, p1, p2, p3: ColorRef]) {.base.} =
+  self.corners = corners

+ 3 - 0
src/nodesnim/nodescontrol/control.nim

@@ -138,6 +138,9 @@ method handle*(self: ControlRef, event: InputEvent, mouse_on: var NodeRef) =
     self.pressed = false
     self.on_release(self, event.x, event.y)
 
+method setBackground*(self: ControlRef, drawable: DrawableRef) {.base.} =
+  self.background = drawable
+
 method setBackgroundColor*(self: ControlRef, color: ColorRef) {.base.} =
   ## Changes Control background color.
   self.background.setColor(color)

+ 1 - 1
src/nodesnim/window.nim

@@ -279,7 +279,7 @@ proc Window*(title: cstring, w: cint = 640, h: cint = 360) {.cdecl.} =
   # Set up OpenGL
   let (r, g, b, a) = env.color.toFloatTuple()
   glClearColor(r, g, b, a)
-  glShadeModel(GL_FLAT)
+  glShadeModel(GL_SMOOTH)
   glClear(GL_COLOR_BUFFER_BIT)
   glEnable(GL_COLOR_MATERIAL)
   glMaterialf(GL_FRONT, GL_SHININESS, 15)

+ 1 - 0
tests/README.md

@@ -44,3 +44,4 @@
 - [Use StyleSheet object.](https://github.com/Ethosa/nodesnim/blob/master/tests/test42.nim)
 - [Use Drawable and Control.](https://github.com/Ethosa/nodesnim/blob/master/tests/test43.nim)
 - [Use CheckBox node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test44.nim)
+- [Use GradientDrawable and Control.](https://github.com/Ethosa/nodesnim/blob/master/tests/test45.nim)

+ 0 - 1
tests/test43.nim

@@ -9,7 +9,6 @@ build:
     - Control ctrl
 
 
-scene.addChild(ctrl)
 ctrl.resize(256, 96)
 ctrl.move(64, 64)
 ctrl.setStyle(style(

+ 25 - 0
tests/test45.nim

@@ -0,0 +1,25 @@
+# --- Test 45. Use GradientDrawable and Control. --- #
+import nodesnim
+
+
+Window("drawable oops")
+
+build:
+  - Scene scene:
+    - Control ctrl:
+      call resize(100, 150)
+      call move(150, 50)
+
+var gradient = GradientDrawable()
+gradient.setCornerRadius(16)
+gradient.setCornerDetail(16)
+gradient.enableShadow(true)
+gradient.setShadowOffset(Vector2(15, 15))
+gradient.setBorderColor(Color(1.0, 0.5, 0.5, 0.1))
+gradient.setBorderWidth(5)
+
+ctrl.setBackground(gradient)
+
+
+addMainScene(scene)
+windowLaunch()

+ 1 - 2
tests/test9.nim

@@ -11,11 +11,10 @@ var
 
 main.addChild(label)
 
-label.setText("Hello, world!\nsecondline\nThis is a long sentence.111111111111111111фывфывфывыфв")  # Change label text.
+label.setText("Hello, world!\nsecondline\nThis is a long sentence.")  # Change label text.
 label.setTextAlign(0.2, 0.5, 0.2, 0.5)  # try to change it ^^.
 label.setSizeAnchor(1, 1)
 label.setTextColor(Color(1f, 1f, 1f))  # default text color.
-echo label.text.font.isNil()
 
 addScene(main)
 setMainScene("Main")