Quellcode durchsuchen

add Box node, fix bugs.

SakiKawasaki vor 5 Jahren
Ursprung
Commit
795fa9ed92

+ 3 - 2
src/nodesnim.nim

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

+ 6 - 1
src/nodesnim/core/anchor.nim

@@ -15,5 +15,10 @@ proc Anchor*(x1, y1, x2, y2: float): AnchorRef {.inline.} =
 proc Anchor*(vec1, vec2: Vector2Ref): AnchorRef {.inline.} =
   AnchorRef(x1: vec1.x, y1: vec1.y, x2: vec2.x, y2: vec2.y)
 
-func isEmpty*(a: AnchorRef): bool {.inline.} =
+proc isEmpty*(a: AnchorRef): bool =
+  ## Returns true, if a is Anchor(0, 0, 0, 0)
   a.x1 == 0 and a.x2 == 0 and a.y1 == 0 and a.y2 == 0
+
+
+proc `$`*(x: AnchorRef): string =
+  "Anchor(x1: " & $x.x1 & ", y1: " & $x.y1 & ", x2: " & $x.x2 & ", y2: " & $x.y2 & ")"

+ 4 - 4
src/nodesnim/core/color.nim

@@ -77,10 +77,6 @@ proc Color*(): ColorRef {.inline.} =
   ColorRef(r: 0, g: 0, b: 0, a: 0)
 
 
-proc `$`*(color: ColorRef): string =
-  "Color(" & $color.r & ", " & $color.g & ", " & $color.b & ", " & $color.a & ")"
-
-
 proc normalize*(n: float): uint32 {.inline.} =
   if n > 1.0:
     255'u32
@@ -174,3 +170,7 @@ proc lerp*(r1, g1, b1, a1, r2, g2, b2, a2: uint32, lerpv: float): uint32 =
     b = normalizeColor(b1.float * p + b2.float * lerpv).uint32
     a = normalizeColor(a1.float * p + a2.float * lerpv).uint32
   r or (g shl 8) or (b shl 16) or (a shl 24)
+
+
+proc `$`*(color: ColorRef): string =
+  "Color(" & $color.r & ", " & $color.g & ", " & $color.b & ", " & $color.a & ")"

+ 8 - 6
src/nodesnim/core/enums.nim

@@ -2,11 +2,13 @@
 
 type
   MouseMode* {.size: sizeof(int8).} = enum
-    MOUSEMODE_IGNORE = 0x00000001
-    MOUSEMODE_SEE = 0x00000002
+    MOUSEMODE_IGNORE = 0x00000001  ## Igore mouse input. This used in Control nodes
+    MOUSEMODE_SEE = 0x00000002     ## Handle mouse input.
   PauseMode* {.size: sizeof(int8).} = enum
-    PROCESS, PAUSE, INHERIT
+    PROCESS,  ## Continue to work when the window paused.
+    PAUSE,    ## Pause work when the window paused.
+    INHERIT   ## Take parent value.
   TextureMode* {.size: sizeof(int8).} = enum
-    TEXTURE_FILL_XY,
-    TEXTURE_KEEP_ASPECT_RATIO,
-    TEXTURE_CROP
+    TEXTURE_FILL_XY,            ## Fill texture without keeping the aspect ratio.
+    TEXTURE_KEEP_ASPECT_RATIO,  ## Fill texture with keeping the aspect ratio.
+    TEXTURE_CROP                ## Crop and fill texture.

+ 1 - 0
src/nodesnim/core/exceptions.nim

@@ -2,3 +2,4 @@
 
 type
   MainSceneNotLoadedError* = object of ValueError
+  WindowNotCreatedError* = object of ValueError

+ 4 - 0
src/nodesnim/core/rect2.nim

@@ -38,3 +38,7 @@ proc contains*(self, other: Rect2Ref): bool =
    self.hasPoint(other.x+other.w, other.y) and
    self.hasPoint(other.x, other.y+other.h) and
    self.hasPoint(other.x+other.w, other.y+other.h))
+
+
+proc `$`*(x: Rect2Ref): string =
+  "Rect2(x: " & $x.x & ", y: " & $x.y & ", w: " & $x.w & ", h: " & $x.h & ")"

+ 13 - 0
src/nodesnim/core/vector2.nim

@@ -107,5 +107,18 @@ proc `-=`*(x: var Vector2Ref, y: Vector2Ref) =
 proc `/=`*(x: var Vector2Ref, y: Vector2Ref) =
   x = x / y
 
+proc `>`*(x, y: Vector2Ref): bool =
+  x.x > y.x and x.y > y.y
+proc `<`*(x, y: Vector2Ref): bool =
+  x.x < y.x and x.y < y.y
+proc `>=`*(x, y: Vector2Ref): bool =
+  x.x >= y.x and x.y >= y.y
+proc `<=`*(x, y: Vector2Ref): bool =
+  x.x <= y.x and x.y <= y.y
+proc `==`*(x, y: Vector2Ref): bool =
+  x.x == y.x and x.y == y.y
+proc `!=`*(x, y: Vector2Ref): bool =
+  x.x != y.x and x.y != y.y
+
 proc `$`*(a: Vector2Ref): string =
   "Vector2(" & $a.x & ", " & $a.y & ")"

+ 2 - 2
src/nodesnim/nodes/canvas.nim

@@ -150,5 +150,5 @@ method fill*(canvas: CanvasPtr, color: ColorRef) {.base.} =
 method resize*(canvas: CanvasPtr, w, h: GLfloat) {.base.} =
   canvas.rect_size.x = w
   canvas.rect_size.y = h
-  canvas.anchor = nil
-  canvas.size_anchor = nil
+  canvas.can_use_anchor = false
+  canvas.can_use_size_anchor = false

+ 22 - 6
src/nodesnim/nodes/node.nim

@@ -15,6 +15,8 @@ type
   NodeObj* = object of RootObj
     visible*: bool
     is_ready*: bool
+    can_use_anchor*: bool
+    can_use_size_anchor*: bool
     pausemode*: PauseMode            ## Pause mode, by default is INHERIT.
     name*: string                    ## Node name.
     position*: Vector2Ref            ## Node position, by default is Vector2(0, 0).
@@ -34,16 +36,17 @@ type
 
 template nodepattern*(nodetype: untyped): untyped =
   variable = `nodetype`(
-    name: name, position: Vector2(0.0, 0.0), children: @[],
-    global_position: Vector2(0.0, 0.0),
-    rect_size: Vector2(0, 0),
+    name: name, position: Vector2(), children: @[],
+    global_position: Vector2(),
+    rect_size: Vector2(),
     ready: proc() = discard,
     process: proc() = discard,
     input: proc(event: InputEvent) = discard,
     enter: proc() = discard,
     exit: proc() = discard,
     is_ready: false, pausemode: INHERIT, visible: true,
-    anchor: nil, size_anchor: nil
+    anchor: Anchor(0, 0, 0, 0), size_anchor: Vector2(), can_use_anchor: false,
+    can_use_size_anchor: false
   )
   result = variable.addr
 
@@ -202,8 +205,8 @@ method move*(self: NodePtr, vec2: Vector2Ref) {.base, inline.} =
   ## Arguments:
   ## - `vec2`: how much to add to the position on the X,Y axes.
   self.position += vec2
-  self.anchor = nil
-  self.size_anchor = nil
+  self.can_use_anchor = false
+  self.can_use_size_anchor = false
 
 method removeChild*(self: NodePtr, index: int) {.base.} =
   ## Removes node child at a specific position.
@@ -224,6 +227,19 @@ method removeChild*(self: NodePtr, other: NodePtr) {.base.} =
 
 method setAnchor*(self: NodePtr, anchor: AnchorRef) {.base.} =
   self.anchor = anchor
+  self.can_use_anchor = true
+
+method setAnchor*(self: NodePtr, x1, y1, x2, y2: float) {.base.} =
+  self.anchor = Anchor(x1, y1, x2, y2)
+  self.can_use_anchor = true
+
+method setSizeAnchor*(self: NodePtr, anchor: Vector2Ref) {.base.} =
+  self.size_anchor = anchor
+  self.can_use_size_anchor = true
+
+method setSizeAnchor*(self: NodePtr, x, y: float) {.base.} =
+  self.size_anchor = Vector2(x, y)
+  self.can_use_size_anchor = true
 
 method delete*(self: NodePtr) {.base.} =
   ## Deletes current node.

+ 49 - 0
src/nodesnim/nodescontrol/box.nim

@@ -0,0 +1,49 @@
+# author: Ethosa
+import
+  ../thirdparty/opengl,
+
+  ../core/vector2,
+  ../core/rect2,
+  ../core/anchor,
+  ../core/input,
+  ../core/enums,
+
+  ../nodes/node,
+  control
+
+
+type
+  BoxObj* = object of ControlPtr
+    child_anchor*: AnchorRef
+  BoxPtr* = ptr BoxObj
+
+
+proc Box*(name: string, variable: var BoxObj): BoxPtr =
+  nodepattern(BoxObj)
+  controlpattern()
+  variable.rect_size.x = 40
+  variable.rect_size.y = 40
+  variable.child_anchor = Anchor(0.5, 0.5, 0.5, 0.5)
+
+proc Box*(obj: var BoxObj): BoxPtr {.inline.} =
+  Box("Box", obj)
+
+
+method addChild*(self: BoxPtr, child: NodePtr) =
+  ## Adds new child in current node.
+  ##
+  ## Arguments:
+  ## - `child`: other node.
+  self.children.add(child)
+  child.parent = self
+  if child.rect_size.x > self.rect_size.x:
+    self.rect_size.x = child.rect_size.x
+  if child.rect_size.y > self.rect_size.y:
+    self.rect_size.y = child.rect_size.y
+
+
+method draw*(self: BoxPtr, w, h: GLfloat) =
+  for child in self.children:
+    child.position.x = self.rect_size.x*self.child_anchor.x1 - child.rect_size.x*self.child_anchor.x2
+    child.position.y = self.rect_size.y*self.child_anchor.y1 - child.rect_size.y*self.child_anchor.y2
+  procCall self.ControlPtr.draw(w, h)

+ 8 - 7
src/nodesnim/nodescontrol/button.nim

@@ -20,15 +20,15 @@ type
     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
+    normal_background_color*: ColorRef  ## color, when button is not pressed and not hovered.
+    hover_background_color*: ColorRef   ## color, when button hovered.
+    press_background_color*: ColorRef   ## color, when button pressed.
 
-    normal_color*: ColorRef
-    hover_color*: ColorRef
-    press_color*: ColorRef
+    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
+    on_click*: proc(x, y: float): void  ## This called, when user clicks on button.
   ButtonPtr* = ptr ButtonObj
 
 
@@ -51,6 +51,7 @@ proc Button*(name: string, variable: var ButtonObj): ButtonPtr =
   variable.normal_background_color = Color(0x444444ff)
   variable.hover_background_color = Color(0x505050ff)
   variable.press_background_color = Color(0x595959ff)
+  variable.on_click = proc(x, y: float) = discard
 
 proc Button*(obj: var ButtonObj): ButtonPtr {.inline.} =
   Button("Button", obj)

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

@@ -55,12 +55,12 @@ proc Control*(obj: var ControlObj): ControlPtr {.inline.} =
 
 method calcPositionAnchor*(self: ControlPtr) =
   if self.parent != nil:
-    if self.size_anchor != nil:
+    if self.can_use_size_anchor:
       if self.size_anchor.x > 0.0:
         self.rect_size.x = self.parent.rect_size.x * self.size_anchor.x
       if self.size_anchor.y > 0.0:
         self.rect_size.y = self.parent.rect_size.y * self.size_anchor.y
-    if self.anchor != nil:
+    if self.can_use_anchor:
       self.position.x = self.parent.rect_size.x*self.anchor.x1 - self.rect_size.x*self.anchor.x2
       self.position.y = self.parent.rect_size.y*self.anchor.y1 - self.rect_size.y*self.anchor.y2
 
@@ -72,6 +72,7 @@ method draw*(self: ControlPtr, w, h: GLfloat) =
     self.press(last_event.x, last_event.y)
 
 method getGlobalMousePosition*(self: ControlPtr): Vector2Ref {.base, inline.} =
+  ## Returns mouse position.
   Vector2Ref(x: last_event.x, y: last_event.y)
 
 method handle*(self: ControlPtr, event: InputEvent, mouse_on: var NodePtr) =

+ 1 - 1
src/nodesnim/thirdparty/opengl/glu.nim

@@ -8,7 +8,7 @@
 # For the latest updates, visit Delphi3D: http://www.delphi3d.net
 #******************************************************************************
 
-import opengl
+import ../opengl
 
 {.deadCodeElim: on.}
 

+ 1 - 1
src/nodesnim/thirdparty/opengl/glut.nim

@@ -15,7 +15,7 @@
 #   For the latest updates, visit Delphi3D: http://www.delphi3d.net
 #******************************************************************************
 
-import opengl
+import ../opengl
 
 {.deadCodeElim: on.}
 

+ 1 - 1
src/nodesnim/thirdparty/opengl/glx.nim

@@ -23,7 +23,7 @@
 #  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 #
 
-import x11/x, x11/xlib, x11/xutil, opengl
+import x11/x, x11/xlib, x11/xutil, ../opengl
 
 {.deadCodeElim: on.}
 

+ 1 - 1
src/nodesnim/thirdparty/opengl/wingl.nim

@@ -1,4 +1,4 @@
-import opengl, windows
+import ../opengl, windows
 
 {.deadCodeElim: on.}
 

+ 1 - 1
src/nodesnim/thirdparty/sdl2/audio.nim

@@ -1,4 +1,4 @@
-import sdl2
+import ../sdl2
 #
 #  Simple DirectMedia Layer
 #  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>

+ 1 - 1
src/nodesnim/thirdparty/sdl2/gfx.nim

@@ -29,7 +29,7 @@
 
 # Docs: http://www.ferzkopp.net/Software/SDL_gfx-2.0/Docs/html/_s_d_l__gfx_primitives_8c.html
 
-import sdl2
+import ../sdl2
 
 when not defined(SDL_Static):
   when defined(windows):

+ 1 - 1
src/nodesnim/thirdparty/sdl2/mixer.nim

@@ -35,7 +35,7 @@ else:
 when not defined(SDL_Static):
   {.push callConv:cdecl, dynlib: LibName.}
 
-import sdl2, sdl2.audio
+import ../sdl2, audio
 
 when system.cpuEndian == littleEndian: # SDL_BYTEORDER == SDL_LIL_ENDIAN
   const

+ 1 - 1
src/nodesnim/thirdparty/sdl2/net.nim

@@ -20,7 +20,7 @@
 #  3. This notice may not be removed or altered from any source distribution.
 #
 # $Id$
-import sdl2
+import ../sdl2
 
 when not defined(SDL_Static):
   when defined(windows):

+ 10 - 1
src/nodesnim/window.nim

@@ -31,7 +31,9 @@ var
 
 
 # --- Callbacks --- #
-var mouse_on: NodePtr = nil
+var
+  mouse_on: NodePtr = nil
+  window_created: bool = false
 
 proc display {.cdecl.} =
   ## Displays window.
@@ -171,6 +173,12 @@ proc setMainScene*(name: string) =
       main_scene = scene
       break
 
+proc setTitle*(title: cstring) =
+  ## Changes window title.
+  if not window_created:
+    raise newException(WindowNotCreatedError, "Window not created!")
+  glutSetWindowTitle(title)
+
 proc Window*(title: cstring, w: cint = 640, h: cint = 360) {.cdecl.} =
   ## Creates a new window pointer
   ##
@@ -188,6 +196,7 @@ proc Window*(title: cstring, w: cint = 640, h: cint = 360) {.cdecl.} =
   glClear(GL_COLOR_BUFFER_BIT)
 
   reshape(w, h)
+  window_created = true
 
 
 proc windowLaunch* =

+ 1 - 1
tests/test10.nim

@@ -15,7 +15,7 @@ main.addChild(button)
 
 button.text = "Press me!"
 button.resize(256, 64)
-button.anchor = Anchor(0.5, 0.5, 0.5, 0.5)
+button.setAnchor(0.5, 0.5, 0.5, 0.5)
 
 
 button.on_click =

+ 45 - 0
tests/test12.nim

@@ -0,0 +1,45 @@
+# --- Test 12. Use Box node. --- #
+import nodesnim
+
+
+Window("hello world")
+
+var
+  mainobj: SceneObj
+  main = Scene("Main", mainobj)
+
+  boxobj: BoxObj     # Create a BoxObj.
+  box = Box(boxobj)  # Create pointer to the BoxObj.
+
+  redobj: ColorRectObj
+  red = ColorRect(redobj)  # #ff6699
+
+  pinkobj: ColorRectObj
+  pink = ColorRect(pinkobj)  #ff64ff
+
+  orangeobj: ColorRectObj
+  orange = ColorRect(orangeobj)  # #ffaa00
+
+
+red.color = Color(0xff6699ff'u32)
+pink.color = Color(0xff64ffff'u32)
+orange.color = Color(0xffaa00ff'u32)
+
+red.resize(128, 128)
+pink.resize(64, 64)
+orange.resize(32, 32)
+
+# Add rects in the Box node.
+box.addChild(red)
+box.addChild(pink)
+box.addChild(orange)
+
+main.addChild(box)
+box.setAnchor(0, 0.5, 0, 0.5)  # Box anchor in the scene.
+
+# Box node keeps child nodes in the Box center.
+
+
+addScene(main)
+setMainScene("Main")
+windowLaunch()

+ 3 - 3
tests/test6.nim

@@ -21,14 +21,14 @@ lightblue.addChild(violet)
 lightblue.resize(256, 128)
 lightblue.move(128, 64)
 
-violet.anchor = Anchor(  # Try to change it! ^^
+violet.setAnchor(  # Try to change it! ^^
   0.5,  # parent anchor at X-axis.
   0.5,  # parent anchor at Y-axis.
   0.5,  # anchor at X-axis.
   0.5   # anchor at Y-axis.
 )
-lightblue.anchor = Anchor(1, 1, 1, 1)
-lightblue.size_anchor = Vector2(
+lightblue.setAnchor(1, 1, 1, 1)
+lightblue.setSizeAnchor(
   0,  # size anchor at X-axis. If 0 then not used.
   1   # size anchor at Y-axis. If 0 then not used.
 )

+ 1 - 1
tests/test7.nim

@@ -25,7 +25,7 @@ second.addChild(lightblue)
 
 violet.color = Color(0xccaaffff'u32)
 lightblue.color = Color(0xaaccffff'u32)
-lightblue.anchor = Anchor(0.5, 0.5, 0.5, 0.5)
+lightblue.setAnchor(0.5, 0.5, 0.5, 0.5)
 
 violet.process =
   proc() =

+ 1 - 1
tests/test9.nim

@@ -15,7 +15,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.setSizeAnchor(1, 1)
 label.color = Color(1f, 1f, 1f)  # default text color.