Quellcode durchsuchen

add `TreeView` (#42)

Ethosa vor 3 Jahren
Ursprung
Commit
4a9c8bfe46

+ 2 - 0
.github/ISSUE_TEMPLATE/bug_report.md

@@ -27,12 +27,14 @@ If applicable, add screenshots to help explain your problem.
  - OS: [e.g. iOS]
  - Browser [e.g. chrome, safari]
  - Version [e.g. 22]
+ - NodesNim version [e.g. 0.5.0]
 
 **Smartphone (please complete the following information):**
  - Device: [e.g. iPhone6]
  - OS: [e.g. iOS8.1]
  - Browser [e.g. stock browser, safari]
  - Version [e.g. 22]
+ - NodesNim version [e.g. 0.5.0]
 
 **Additional context**
 Add any other context about the problem here.

+ 3 - 2
src/nodesnim/core.nim

@@ -20,10 +20,11 @@ import
   core/tileset,
   core/themes,
   core/chartdata,
-  core/glsl
+  core/glsl,
+  core/tree
 
 export
   vector2, rect2, circle, polygon2, enums, anchor, color,
   exceptions, input, image, audio_stream,
   animation, nodes_os, vector3, scene_builder, stylesheet,
-  tools, font, tileset, themes, chartdata, glsl
+  tools, font, tileset, themes, chartdata, glsl, tree

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

@@ -52,6 +52,7 @@ type
     SUB_WINDOW_NODE,
     TOOLTIP_NODE,
     CHART_NODE,
+    TREE_VIEW_NODE,
     # 3D nodes
     NODE3D_NODE,
     GEOMETRY_INSTANCE_NODE,

+ 11 - 0
src/nodesnim/core/glsl.nim

@@ -43,5 +43,16 @@ proc GLSLShaderFile*(vertex_shader, fragment_shader: string): GLSLShaderObj =
 proc use*(shader: GLSLShaderObj) =
   glUseProgram(shader.id)
 
+proc unuse*(shader: GLSLShaderObj) =
+  glUseProgram(0)
+
+proc uniform*[T](shader: GLSLShaderObj, uniform_name: cstring, value: T) =
+  if T is SomeInteger | Glint | bool:
+    glUniform1i(glGetUniformLocation(shader.id, uniform_name), value.int)
+  elif T is SomeFloat | Glfloat:
+    glUniform1f(glGetUniformLocation(shader.id, uniform_name), value.Glfloat)
+  else:
+    throwError(ValueError, "..")
+
 proc freeMemory*(shader: GLSLShaderObj) =
   glDeleteProgram(shader.id)

+ 64 - 0
src/nodesnim/core/tree.nim

@@ -0,0 +1,64 @@
+# author: Ethosa
+## Provides working with TreeView.
+import
+  exceptions,
+  ../thirdparty/gl,
+  ../nodes/node,
+  strutils
+
+type
+  TreeRef* = ref object
+    parent*: TreeRef
+    tree*: seq[TreeRef]
+    level*: uint
+    icon*: Gluint
+    data*: string
+
+
+proc Tree*(data: string = "", level: uint = 0): TreeRef =
+  TreeRef(level: level, tree: @[], data: data, parent: nil, icon: 0'u32)
+
+
+proc addTree*(tree: TreeRef, data: string = "") =
+  tree.tree.add(TreeRef(level: tree.level + 1, tree: @[], data: data, parent: tree, icon: 0'u32))
+
+proc addTree*(tree, other: TreeRef) =
+  other.parent = tree
+  tree.tree.add(other)
+
+proc index*(tree: TreeRef): seq[int] =
+  result = @[]
+  var t = tree
+  while not t.parent.isNil():
+    result.add(t.parent.tree.find(t))
+    t = t.parent
+
+proc getTreeAt*(tree: TreeRef, index: openarray[int]): TreeRef =
+  var t = tree
+  for i in index:
+    if t.tree.len() <= i:
+      throwError(ValueError, "Can't get tree at " & $index)
+    t = t.tree[i]
+  t
+
+proc getTreeIter*(tree: TreeRef): seq[TreeRef] =
+  result = @[]
+  if tree.level == 0:
+    result.add(tree)
+  for i in tree.tree:
+    result.add(i)
+    for t in i.getTreeIter():
+      result.add(t)
+
+proc toTree*(node: NodeRef, level: uint = 0): TreeRef =
+  result = Tree(node.name, level)
+  var lvl = level + 1
+  for child in node.children:
+    result.addTree(child.toTree(lvl))
+  if lvl > 1:
+    dec lvl
+
+proc `$`*(tree: TreeRef): string =
+  result = ""
+  for t in tree.getTreeIter():
+    result &= " ".repeat(t.level) & t.data & "\n"

+ 4 - 2
src/nodesnim/nodescontrol.nim

@@ -20,10 +20,12 @@ import
   nodescontrol/subwindow,
   nodescontrol/checkbox,
   nodescontrol/tooltip,
-  nodescontrol/chart
+  nodescontrol/chart,
+  nodescontrol/treeview
 
 export
   control, color_rect, texture_rect, label, button,
   box, hbox, vbox, grid_box, edittext, scroll, progress_bar,
   slider, popup, texture_button, texture_progress_bar,
-  counter, switch, subwindow, checkbox, tooltip, chart
+  counter, switch, subwindow, checkbox, tooltip, chart,
+  treeview

+ 112 - 0
src/nodesnim/nodescontrol/treeview.nim

@@ -0,0 +1,112 @@
+# author: Ethosa
+import
+  ../thirdparty/gl,
+  ../core/enums,
+  ../core/vector2,
+  ../core/anchor,
+  ../core/input,
+  ../core/font,
+  ../core/color,
+  ../core/themes,
+  ../core/tree,
+  ../graphics/drawable,
+  ../nodes/node,
+  ../nodes/canvas,
+  ../private/templates,
+  control
+
+
+type
+  TreeViewItemSelected* = proc(self: TreeViewRef, index: seq[int])
+  TreeViewObj* = object of ControlObj
+    tree*: TreeRef
+    on_item_select*: TreeViewItemSelected
+    use_icons*: bool
+    show_lines*: bool
+    level_width*: float
+  TreeViewRef* = ref TreeViewObj
+
+let
+  tree_view_item_selected_handler =
+    proc(self: TreeViewRef, index: seq[int]) =
+      discard
+
+
+proc TreeView*(name: string = "TreeView"): TreeViewRef =
+  nodepattern(TreeViewRef)
+  controlpattern()
+  result.tree = Tree("tree")
+  result.on_item_select = tree_view_item_selected_handler
+  result.level_width = 30f
+  result.use_icons = false
+  result.show_lines = true
+  result.kind = TREE_VIEW_NODE
+
+
+method draw*(self: TreeViewRef, w, h: GLfloat) =
+  procCall self.ControlRef.draw(w, h)
+  let
+    x = -w/2 + self.global_position.x
+    y = h/2 - self.global_position.y
+    offset = if self.use_icons:
+               20f
+             else:
+               0f
+    arr = self.tree.getTreeIter()
+  var
+    count = 0f
+    width = 0f
+    height = 0f
+
+  glEnable(GL_TEXTURE_2D)
+  for t in arr:
+    let
+      text = stext(t.data)
+      size = text.getTextSize()
+      x_offset = x + t.level.float*self.level_width
+      y_offset = y - count*size.y
+    text.renderTo(Vector2(x_offset + offset, y_offset), size, Anchor())
+
+    if x_offset + offset > width:
+      width = x_offset + offset
+    if y_offset > height:
+      height = y_offset
+
+    glColor(current_theme~accent_dark)
+    glLineWidth(1)
+    if self.show_lines and not t.parent.isNil():
+      let parent_index = arr.find(t.parent).float + 1
+      glBegin(GL_LINE_STRIP)
+      glVertex2f(x_offset, y_offset - size.y/2)
+      glVertex2f(x + 10 + t.parent.level.float*self.level_width, y_offset - size.y/2)
+      glVertex2f(x + 10 + t.parent.level.float*self.level_width, y - parent_index*size.y)
+      glEnd()
+
+    # TODO: fix.
+    glColor4f(1, 1, 1, 1)
+    if self.use_icons:
+      if t.icon > 0u32:
+        glBindTexture(GL_TEXTURE_2D, t.icon)
+        glBegin(GL_QUADS)
+        glTexCoord2f(0, 0)
+        glVertex2f(x_offset, y_offset)
+        glTexCoord2f(1, 0)
+        glVertex2f(x_offset + size.y, y_offset)
+        glTexCoord2f(1, 1)
+        glVertex2f(x_offset + size.y, y_offset - size.y)
+        glTexCoord2f(0, 1)
+        glVertex2f(x_offset, y_offset - size.y)
+        glEnd()
+        glBindTexture(GL_TEXTURE_2D, 0)
+    text.freeMemory()
+    count += 1
+  glDisable(GL_TEXTURE_2D)
+  self.resize(width, height)
+
+method handle*(self: TreeViewRef, event: InputEvent, mouse_on: var NodeRef) =
+  {.warning[LockLevel]: off.}
+  procCall self.ControlRef.handle(event, mouse_on)
+
+
+method bindTree*(self: TreeViewRef, tree: TreeRef) {.base.} =
+  self.tree = tree

+ 0 - 1
src/nodesnim/private/templates.nim

@@ -1,6 +1,5 @@
 # author: Ethosa
 
-
 template voidTemplate* = discard
 
 

+ 3 - 2
src/nodesnim/runtime/scene_loader.nim

@@ -75,9 +75,10 @@ var
 mkparse(Node, Scene, AudioStreamPlayer, AnimationPlayer)
 mkparse(Control, Box, VBox, HBox, ColorRect, Label, SubWindow, ToolTip,
         Button, EditText, TextureButton, TextureRect, GridBox, CheckBox, Chart,
-        Slider, Switch, Popup, Scroll, Counter, ProgressBar, TextureProgressBar)
+        Slider, Switch, Popup, Scroll, Counter, ProgressBar, TextureProgressBar,
+        TreeView)
 mkparse(Node2D, Sprite, AnimatedSprite, KinematicBody2D, CollisionShape2D, TileMap, Camera2D, YSort)
-mkparse(Node3D, Sprite3D, GeometryInstance)
+mkparse(Node3D, Sprite3D, GeometryInstancem, Camera3D)
 
 mkattrs attrs(node, value):
   "color":

BIN
tests/assets/file.png


+ 10 - 0
tests/test3.nim

@@ -1,4 +1,5 @@
 # --- Test 3. Work with Control nodes. --- #
+# To change scene press SPACE.
 import
   nodesnim,
   unittest
@@ -396,6 +397,15 @@ suite "Work with Control nodes.":
 
     getSceneByName("main").addChildren(spiderweb_chart)
 
+  test "Treeview test":
+    build:
+      - TreeView tree:
+        call:
+          bindTree(getSceneByName("main").toTree())
+    echo tree.tree
+
+    getSceneByName("second_scene").addChild(tree)
+
 
   test "Launch window":
     windowLaunch()

+ 6 - 31
tests/test7.nim

@@ -27,24 +27,24 @@ suite "Work with 3D nodes.":
     build:
       - GeometryInstance cube:
         translation: Vector3(-1, 0, 2)
-        color: Color(122, 133, 144, 0.8)
+        color: Color(122, 133, 144)
       - GeometryInstance cube1:
         translation: Vector3(2, 0, -2)
-        color: Color(144, 144, 122, 0.8)
+        color: Color(144, 144, 122)
       - GeometryInstance cube2:
         translation: Vector3(1, 2.5, 1)
-        color: Color(144, 111, 144, 0.8)
+        color: Color(144, 111, 144)
       - GeometryInstance sphere:
         translation: Vector3(-1, -1, 1)
-        color: Color(144, 77, 144, 1.0)
+        color: Color(144, 77, 144)
         geometry: GEOMETRY_SPHERE
       - GeometryInstance cylinder:
         translation: Vector3(2, -1, 1)
-        color: Color(144, 77, 144, 1.0)
+        color: Color(144, 77, 144)
         geometry: GEOMETRY_CYLINDER
       - GeometryInstance polygon:
         translation: Vector3(2, -2, 1)
-        color: Color(144, 77, 144, 1.0)
+        color: Color(144, 77, 144)
         geometry: GEOMETRY_POLYGON
         points: @[
           Vector3(), Vector3(100, 10, 0), Vector3(0, 10, -10),
@@ -87,31 +87,6 @@ suite "Work with 3D nodes.":
       sprite.rotateY(0.5)
     getSceneByName("main").addChild(sprite)
 
-  test "Shaders test":
-    var shader = GLSLShader(
-      """#version 330 core
-    layout (location = 0) in vec3 position;
-
-    out vec4 vertexColor;
-
-    void main()
-    {
-        gl_Position = vec4(position, 1.0);
-        vertexColor = vec4(0.5f, 0.0f, 0.0f, 1.0f);
-    }""",
-
-    """#version 330 core
-    in vec4 vertexColor;
-
-    out vec4 color;
-
-    void main()
-    {
-        color = vertexColor;
-    } """
-    )
-    shader.use()
-
 
   test "Launch window":
     windowLaunch()