Explorar el Código

add Button node.

Ethosa hace 5 años
padre
commit
448983541a

+ 3 - 2
src/nodesnim.nim

@@ -21,11 +21,12 @@ import
   nodesnim/nodescontrol/control,
   nodesnim/nodescontrol/color_rect,
   nodesnim/nodescontrol/texture_rect,
-  nodesnim/nodescontrol/label
+  nodesnim/nodescontrol/label,
+  nodesnim/nodescontrol/button
 
 export
   opengl, glut,
   window, environment,
   vector2, rect2, enums, anchor, color, exceptions, input, image,
   node, scene, canvas,
-  control, color_rect, texture_rect, label
+  control, color_rect, texture_rect, label, button

+ 3 - 0
src/nodesnim/core/input.nim

@@ -38,6 +38,9 @@ const
   BUTTON_MIDDLE* = 1
   BUTTON_RIGHT* = 2
 
+  BUTTON_RELEASE* = 0
+  BUTTON_CLICK* = 1
+
   K_F1* = 1
   K_F2* = 2
   K_F3* = 3

+ 76 - 0
src/nodesnim/nodescontrol/button.nim

@@ -0,0 +1,76 @@
+# author: Ethosa
+import
+  ../thirdparty/opengl,
+  ../thirdparty/opengl/glut,
+
+  ../core/vector2,
+  ../core/rect2,
+  ../core/anchor,
+  ../core/input,
+  ../core/enums,
+  ../core/color,
+
+  ../nodes/node,
+  control,
+  label
+
+
+type
+  ButtonObj* = object of LabelObj
+    button_mask*: cint  ## Mask for handle clicks
+    action_mask*: cint  ## BUTTON_RELEASE or BUTTON_CLICK.
+
+    normal_background_color*: ColorRef
+    hover_background_color*: ColorRef
+    press_background_color*: ColorRef
+
+    on_click*: proc(x, y: float): void
+  ButtonPtr* = ptr ButtonObj
+
+
+proc Button*(name: string, variable: var ButtonObj): ButtonPtr =
+  nodepattern(ButtonObj)
+  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.button_mask = BUTTON_LEFT
+  variable.action_mask = BUTTON_RELEASE
+  variable.normal_background_color = Color(0x444444ff)
+  variable.hover_background_color = Color(0x505050ff)
+  variable.press_background_color = Color(0x595959ff)
+
+proc Button*(obj: var ButtonObj): ButtonPtr {.inline.} =
+  Button("Button", obj)
+
+
+method draw*(self: ButtonPtr, w, h: GLfloat) =
+  self.calcGlobalPosition()
+  let
+    x = -w/2 + self.global_position.x
+    y = h/2 - self.global_position.y
+    color =
+      if self.pressed:
+        self.press_background_color
+      elif self.hovered:
+        self.hover_background_color
+      else:
+        self.normal_background_color
+  glColor4f(color.r, color.g, color.b, color.a)
+  glRectf(x, y, x + self.rect_size.x, y - self.rect_size.y)
+  procCall self.LabelPtr.draw(w, h)
+
+
+method handle*(self: ButtonPtr, event: InputEvent, mouse_on: var NodePtr) =
+  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)

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

@@ -6,6 +6,7 @@ import
   ../core/rect2,
   ../core/anchor,
   ../core/input,
+  ../core/enums,
 
   ../nodes/node,
   ../nodes/canvas
@@ -17,6 +18,8 @@ type
     pressed*: bool
     focused*: bool
 
+    mousemode*: MouseMode
+
     mouse_enter*: proc(x, y: float): void  ## This called when the mouse enters the Control node.
     mouse_exit*: proc(x, y: float): void   ## This called when the mouse exit from the Control node.
     click*: proc(x, y: float): void        ## This called when the user clicks on the Control node.
@@ -32,6 +35,8 @@ template controlpattern*: untyped =
   variable.focused = false
   variable.pressed = false
 
+  variable.mousemode = MOUSEMODE_SEE
+
   variable.mouse_enter = proc(x, y: float) = discard
   variable.mouse_exit = proc(x, y: float) = discard
   variable.click = proc(x, y: float) = discard
@@ -71,6 +76,8 @@ method getGlobalMousePosition*(self: ControlPtr): Vector2Ref {.base, inline.} =
 
 method handle*(self: ControlPtr, event: InputEvent, mouse_on: var NodePtr) =
   {.warning[LockLevel]: off.}
+  if self.mousemode == MOUSEMODE_IGNORE:
+    return
   let
     hasmouse = Rect2(self.global_position, self.rect_size).hasPoint(event.x, event.y)
     click = mouse_pressed and event.kind == MOUSE

+ 4 - 4
src/nodesnim/nodescontrol/label.nim

@@ -49,13 +49,13 @@ method draw*(self: LabelPtr, w, h: GLfloat) =
     y = h/2 - self.global_position.y
 
   glColor4f(self.color.r, self.color.g, self.color.b, self.color.a)
-  var
-    th = 0f
-    ty = 0f
+  var th = 0f
 
   for line in self.text.splitLines():  # get text height
     th += self.spacing + self.size
-  ty = y - self.rect_size.y*self.text_align.y1 + th * self.text_align.y2
+  if th != 0:
+    th -= self.spacing
+  var ty = y - self.rect_size.y*self.text_align.y1 + th*self.text_align.y2
 
   for line in self.text.splitLines():
     var tw = self.font.glutBitmapLength(line).float

+ 1 - 0
tests/README.md

@@ -9,3 +9,4 @@
 7. [Change scenes.](https://github.com/Ethosa/nodesnim/blob/master/tests/test7.nim)
 8. [Use TextureRect node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test8.nim)
 9. [Use Label node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test9.nim)
+10. [Use Button node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test10.nim)

+ 28 - 0
tests/test10.nim

@@ -0,0 +1,28 @@
+# --- Test 10. Use Button node. --- #
+import nodesnim
+
+
+Window("hello world")
+
+var
+  mainobj: SceneObj
+  main = Scene("Main", mainobj)
+
+  buttonobj: ButtonObj
+  button = Button(buttonobj)
+
+main.addChild(button)
+
+button.text = "Press me!"
+button.resize(256, 64)
+button.anchor = Anchor(0.5, 0.5, 0.5, 0.5)
+
+
+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()

+ 1 - 0
tests/test9.nim

@@ -16,6 +16,7 @@ main.addChild(label)
 label.text = "Hello, world!\nsecondline\nThis is a long sentence."  # Change label text.
 label.text_align = Anchor(0.2, 0.5, 0.2, 0.5)  # try to change it ^^.
 label.size_anchor = Vector2(1, 1)
+label.color = Color(1f, 1f, 1f)  # default text color.
 
 
 addScene(main)