瀏覽代碼

add TextureButton node.

SakiKawasaki 5 年之前
父節點
當前提交
f12294e655

+ 1 - 0
README.md

@@ -61,6 +61,7 @@
    -  [VProgressBar](https://ethosa.github.io/nodesnim/vprogress_bar.html)
    -  [VSlider](https://ethosa.github.io/nodesnim/vslider.html)
    -  [Popup](https://ethosa.github.io/nodesnim/popup.html)
+   -  [TextureButton](https://ethosa.github.io/nodesnim/texture_button.html)
 -  2D nodes
    -  [Node2D](https://ethosa.github.io/nodesnim/node2d.html)
    -  [Sprite](https://ethosa.github.io/nodesnim/sprite.html)

+ 2 - 0
src/nodesnim.nim

@@ -39,6 +39,7 @@ import
   nodesnim/nodescontrol/slider,
   nodesnim/nodescontrol/vslider,
   nodesnim/nodescontrol/popup,
+  nodesnim/nodescontrol/texture_button,
 
   nodesnim/nodes2d/node2d,
   nodesnim/nodes2d/sprite
@@ -56,5 +57,6 @@ export
   # Control nodes
   control, color_rect, texture_rect, label, button, box, hbox, vbox, grid_box, edittext,
   rich_label, rich_edit_text, scroll, progress_bar, vprogress_bar, slider, vslider, popup,
+  texture_button,
   # 2D nodes
   node2d, sprite

+ 2 - 0
src/nodesnim/nodescontrol/rich_edit_text.nim

@@ -144,6 +144,8 @@ method draw*(self: RichEditTextPtr, w, h: GLfloat) =
       if tx >= x and tx < x + self.rect_size.x+right and ty <= y and ty > y - self.rect_size.y+bottom:
         glColor4f(c.color.r, c.color.g, c.color.b, c.color.a)
         glRasterPos2f(tx, ty)  # set char position
+        if c.underline:
+          glRectf(tx, ty+self.size, tx+cw, 1)
         self.font.glutBitmapCharacter(c.c.int)  # render char
 
         inc char_num

+ 2 - 0
src/nodesnim/nodescontrol/rich_label.nim

@@ -97,6 +97,8 @@ method draw*(self: RichLabelPtr, w, h: GLfloat) =
         glColor4f(c.color.r, c.color.g, c.color.b, c.color.a)
         glRasterPos2f(tx, ty)  # set char position
         self.font.glutBitmapCharacter(c.c.int)  # render char
+        if c.underline:
+          glRectf(tx, ty+self.size, tx+cw, 1)
       tx += cw
     ty -= self.spacing + self.size
 

+ 144 - 0
src/nodesnim/nodescontrol/texture_button.nim

@@ -0,0 +1,144 @@
+# author: Ethosa
+import
+  ../thirdparty/opengl,
+  ../thirdparty/opengl/glut,
+
+  ../core/vector2,
+  ../core/rect2,
+  ../core/anchor,
+  ../core/input,
+  ../core/enums,
+  ../core/image,
+  ../core/color,
+
+  ../nodes/node,
+  control,
+  label
+
+
+type
+  TextureButtonObj* = object of LabelObj
+    button_mask*: cint  ## Mask for handle clicks
+    action_mask*: cint  ## BUTTON_RELEASE or BUTTON_CLICK.
+
+    normal_background_texture*: GlTextureObj  ## texture, when button is not pressed and not hovered.
+    hover_background_texture*: GlTextureObj   ## texture, when button hovered.
+    press_background_texture*: GlTextureObj   ## texture, when button pressed.
+
+    normal_color*: ColorRef  ## text color, whenwhen button is not pressed and not hovered.
+    hover_color*: ColorRef   ## text color, when button hovered.
+    press_color*: ColorRef   ## text color, when button pressed.
+
+    on_click*: proc(x, y: float): void  ## This called, when user clicks on button.
+  TextureButtonPtr* = ptr TextureButtonObj
+
+
+proc TextureButton*(name: string, variable: var TextureButtonObj): TextureButtonPtr =
+  ## Creates a new TextureButton node pointer.
+  ##
+  ## Arguments:
+  ## - `name` is a node name.
+  ## - `variable` is a TextureButtonObj variable.
+  runnableExamples:
+    var
+      my_button_obj: TextureButtonObj
+      my_button = TextureButton("TextureButton", my_button_obj)
+  nodepattern(TextureButtonObj)
+  controlpattern()
+  variable.rect_size.x = 40
+  variable.rect_size.y = 40
+  variable.text = ""
+  variable.font = GLUT_BITMAP_HELVETICA_12
+  variable.size = 12
+  variable.spacing = 2
+  variable.text_align = Anchor(0.5, 0.5, 0.5, 0.5)
+  variable.color = Color(1f, 1f, 1f)
+  variable.normal_color = Color(1f, 1f, 1f)
+  variable.hover_color = Color(1f, 1f, 1f)
+  variable.press_color = Color(1f, 1f, 1f)
+  variable.button_mask = BUTTON_LEFT
+  variable.action_mask = BUTTON_RELEASE
+  variable.normal_background_texture = GlTextureObj()
+  variable.hover_background_texture = GlTextureObj()
+  variable.press_background_texture = GlTextureObj()
+  variable.on_click = proc(x, y: float) = discard
+
+proc TextureButton*(obj: var TextureButtonObj): TextureButtonPtr {.inline.} =
+  ## Creates a new TextureButton node pointer with default node name "TextureButton".
+  ##
+  ## Arguments:
+  ## - `variable` is a TextureButtonObj variable.
+  runnableExamples:
+    var
+      my_button_obj: TextureButtonObj
+      my_button = TextureButton(my_button_obj)
+  TextureButton("TextureButton", obj)
+
+
+method draw*(self: TextureButtonPtr, w, h: GLfloat) =
+  ## this method uses in the `window.nim`.
+  self.calcGlobalPosition()
+  let
+    x = -w/2 + self.global_position.x
+    y = h/2 - self.global_position.y
+    texture =
+      if self.pressed:
+        self.press_background_texture
+      elif self.hovered:
+        self.hover_background_texture
+      else:
+        self.normal_background_texture
+  self.color =
+    if self.pressed:
+      self.press_color
+    elif self.hovered:
+      self.hover_color
+    else:
+      self.normal_color
+
+  # Texture
+  if texture.texture > 0:
+    glEnable(GL_TEXTURE_2D)
+    glBindTexture(GL_TEXTURE_2D, texture.texture)
+
+    glBegin(GL_QUADS)
+    glTexCoord2f(0, 0)
+    glVertex2f(x, y)
+    glTexCoord2f(0, 1)
+    glVertex2f(x, y - self.rect_size.y)
+    glTexCoord2f(1, 1)
+    glVertex2f(x + self.rect_size.x, y - self.rect_size.y)
+    glTexCoord2f(1, 0)
+    glVertex2f(x + self.rect_size.x, y)
+    glEnd()
+
+    glDisable(GL_TEXTURE_2D)
+
+  procCall self.LabelPtr.draw(w, h)
+
+method duplicate*(self: TextureButtonPtr, obj: var TextureButtonObj): TextureButtonPtr {.base.} =
+  ## Duplicates TextureButton object and creates a new TextureButton node pointer.
+  obj = self[]
+  obj.addr
+
+method handle*(self: TextureButtonPtr, event: InputEvent, mouse_on: var NodePtr) =
+  ## Handles user input. This uses in the `window.nim`.
+  procCall self.ControlPtr.handle(event, mouse_on)
+
+  if self.hovered:
+    if event.kind == MOUSE and self.action_mask == 1 and mouse_pressed and self.button_mask == event.button_index:
+      self.on_click(event.x, event.y)
+    elif event.kind == MOUSE and self.action_mask == 0 and not mouse_pressed and self.button_mask == event.button_index:
+      self.on_click(event.x, event.y)
+
+method setNormalTexture*(self: TextureButtonPtr, texture: GlTextureObj) {.base.} =
+  ## Changes button texture, when it not pressed and not hovered.
+  self.normal_background_texture = texture
+
+method setHoverTexture*(self: TextureButtonPtr, texture: GlTextureObj) {.base.} =
+  ## Changes button texture, when it hovered.
+  self.hover_background_texture = texture
+
+method setPressTexture*(self: TextureButtonPtr, texture: GlTextureObj) {.base.} =
+  ## Changes button texture, when it pressed.
+  self.press_background_texture = texture

+ 1 - 0
tests/README.md

@@ -26,3 +26,4 @@
 24. [Use AudioStreamPlayer node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test24.nim)
 25. [Use Node2D node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test25.nim)
 26. [Use Sprite node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test26.nim)
+27. [Use textureButton node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test27.nim)

二進制
tests/assets/button_hover.png


二進制
tests/assets/button_normal.png


二進制
tests/assets/button_press.png


+ 1 - 1
tests/test26.nim

@@ -17,7 +17,7 @@ var
 main.addChild(sprite)
 
 sprite.move(128, 128)  # Move sprite.
-sprite.setTexture(icon)  # Change sprite image.
+# sprite.setTexture(icon)  # Change sprite image.
 
 sprite.centered = true  # The default value is true. Try to change it.
 

+ 36 - 0
tests/test27.nim

@@ -0,0 +1,36 @@
+# --- Test 27. Use TextureButton node. --- #
+import nodesnim
+
+
+Window("hello world")
+
+var
+  mainobj: SceneObj
+  main = Scene("Main", mainobj)
+
+  buttonobj: TextureButtonObj
+  button = TextureButton(buttonobj)
+
+  norm_texture = load("assets/button_normal.png", GL_RGBA)
+  hover_texture = load("assets/button_hover.png", GL_RGBA)
+  press_texture = load("assets/button_press.png", GL_RGBA)
+
+main.addChild(button)
+env.setBackgroundColor(Color(0xf2f2f7ff'u32))
+
+button.text = "Press me!"
+button.resize(256, 64)
+button.setAnchor(0.5, 0.5, 0.5, 0.5)
+
+button.setNormalTexture(norm_texture)
+button.setHoverTexture(hover_texture)
+button.setPressTexture(press_texture)
+
+button.on_click =
+  proc(x, y: float) =  # This called when user clicks on the button
+    button.text = "Clicked in " & $x & ", " & $y & " position."
+
+
+addScene(main)
+setMainScene("Main")
+windowLaunch()