Bläddra i källkod

fix EditText and RichEditText

SakiKawasaki 5 år sedan
förälder
incheckning
65babef816

+ 3 - 2
src/nodesnim.nim

@@ -4,8 +4,9 @@ when defined(debug):
   var console_logger = newConsoleLogger(fmtStr="[$time]::$levelname - ")
   addHandler(console_logger)
 
-  var file_logger = newFileLogger("logs.log", fmtStr="[$date at $time]::$levelname - ")
-  addHandler(file_logger)
+  when not defined(android):
+    var file_logger = newFileLogger("logs.log", fmtStr="[$date at $time]::$levelname - ")
+    addHandler(file_logger)
 
   info("Compiled in debug mode.")
 

+ 6 - 0
src/nodesnim/nodes2d/kinematic_body2d.nim

@@ -87,6 +87,12 @@ method draw*(self: KinematicBody2DPtr, w, h: GLfloat) =
     self.position = self.timed_position
 
 
+method duplicate*(self: KinematicBody2DPtr, obj: var KinematicBody2DObj): KinematicBody2DPtr {.base.} =
+  ## Duplicates KinematicBody2D and create a new KinematicBody2D pointer.
+  obj = self[]
+  obj.addr
+
+
 method isCollide*(self: KinematicBody2DPtr): bool {.base.} =
   ## Checks any collision and return `true`, when collide with any collision shape.
   result = false

+ 84 - 30
src/nodesnim/nodescontrol/edittext.nim

@@ -91,6 +91,7 @@ method getTextSize*(self: EditTextPtr): Vector2Ref {.base.} =
   if result.y > 0:
     result.y -= self.spacing
 
+
 method getLine*(self: EditTextPtr): int {.base.} =
   ## Returns current caret line.
   var
@@ -107,6 +108,84 @@ method getLine*(self: EditTextPtr): int {.base.} =
     inc caret_pos
   return l
 
+
+method getCharPositionUnderMouse*(self: EditTextPtr): int {.base.} =
+  ## Returns char position under mouse.
+  let
+    size = self.getTextSize()
+    pos = Vector2Ref(x: last_event.x, y: last_event.y) - self.global_position
+  if pos.y > size.y:
+    return self.text.len()
+  else:
+    var
+      res = Vector2()
+      caret_pos = 0
+      current_pos = 0
+    for line in self.text.splitLines():  # get text height
+      var x: float = 0f
+      current_pos = 0
+      res.y += self.spacing + self.size
+      for c in line:
+        x += self.font.glutBitmapWidth(c.int).float
+        inc caret_pos
+        inc current_pos
+        if res.y >= pos.y:
+          if current_pos < line.len() and x <= pos.x:
+            continue
+          return caret_pos
+      inc caret_pos
+      if x > res.x:
+        res.x = x
+
+
+method getCharUnderMouse*(self: EditTextPtr): char {.base.} =
+  ## Returns char under mouse
+  return self.text[self.getCharPositionUnderMouse()]
+
+
+method getWordPositionUnderMouse*(self: EditTextPtr): tuple[startpos, endpos: int] {.base.} =
+  ## Returns words under mouse.
+  ## Returns (-1, -1), if under mouse no founds words.
+  var caret = self.getCharPositionUnderMouse()
+  if caret == self.text.len():
+    return (-1, -1)
+
+  if self.text.len() > 0 and self.text[caret] != ' ':
+    # Left
+    var i = caret
+    while self.text[i] != ' ':
+      dec i
+      if i < 0:
+        break
+    if i > 0:
+      if self.text[i] == ' ':
+        i += 1
+      result.startpos = i
+    else:
+      result.startpos = 0
+    # Right
+    i = caret
+    while self.text[i] != ' ':
+      inc i
+      if i > self.text.len()-1:
+        break
+    if i < self.text.len():
+      if self.text[i] == ' ':
+        i -= 1
+      result.endpos = i
+    else:
+      result.endpos = self.text.len()-1
+  else:
+    return (-1, -1)
+
+
+method getWordUnderMouse*(self: EditTextPtr): string {.base.} =
+  ## Returns words under mouse.
+  let (s, e) = self.getWordPositionUnderMouse()
+  if self.text.len() > 0:
+    return self.text[s..e]
+
+
 method draw*(self: EditTextPtr, w, h: GLfloat) =
   ## This method uses in the `window.nim`
   self.calcGlobalPosition()
@@ -174,6 +253,7 @@ method draw*(self: EditTextPtr, w, h: GLfloat) =
   if self.pressed:
     self.press(last_event.x, last_event.y)
 
+
 method duplicate*(self: EditTextPtr, obj: var EditTextObj): EditTextPtr {.base.} =
   ## Duplicates EditText object and create a new EditText pointer.
   obj = self[]
@@ -190,36 +270,7 @@ method handle*(self: EditTextPtr, event: InputEvent, mouse_on: var NodePtr) =
     glutSetCursor(GLUT_CURSOR_LEFT_ARROW)
 
   if event.kind == MOUSE and event.pressed:
-    let
-      size = self.getTextSize()
-      pos = Vector2Ref(x: event.x, y: event.y) - self.global_position
-    if pos.y > size.y:
-      self.caret_position = self.text.len()
-    else:
-      var
-        res = Vector2()
-        caret_pos = 0
-        current_pos = 0
-        stop = false
-      for line in self.text.splitLines():  # get text height
-        var x: float = 0f
-        current_pos = 0
-        res.y += self.spacing + self.size
-        for c in line:
-          x += self.font.glutBitmapWidth(c.int).float
-          inc caret_pos
-          inc current_pos
-          if res.y >= pos.y:
-            if current_pos < line.len() and x <= pos.x:
-              continue
-            stop = true
-            self.caret_position = caret_pos
-            break
-        if stop:
-          break
-        inc caret_pos
-        if x > res.x:
-          res.x = x
+    self.caret_position = self.getCharPositionUnderMouse()
 
   if self.focused:
     if event.kind == KEYBOARD:
@@ -254,14 +305,17 @@ method handle*(self: EditTextPtr, event: InputEvent, mouse_on: var NodePtr) =
           self.caret_position += 1
           self.on_edit(event.key)
 
+
 method setTextAlign*(self: EditTextPtr, align: AnchorRef) {.base.} =
   ## Changes text align.
   self.text_align = align
 
+
 method setTextAlign*(self: EditTextPtr, x1, y1, x2, y2: float) {.base.} =
   ## Changes text align.
   self.text_align = Anchor(x1, y1, x2, y2)
 
+
 method setText*(self: EditTextPtr, value: string) {.base.} =
   ## Changes EditText text.
   self.text = value

+ 81 - 31
src/nodesnim/nodescontrol/rich_edit_text.nim

@@ -102,6 +102,84 @@ method getLine*(self: RichEditTextPtr): int {.base.} =
     inc caret_pos
   return l
 
+
+method getCharPositionUnderMouse*(self: RichEditTextPtr): int {.base.} =
+  ## Returns char position under mouse.
+  let
+    size = self.getTextSize()
+    pos = Vector2Ref(x: last_event.x, y: last_event.y) - self.global_position
+  if pos.y > size.y:
+    return self.text.len()
+  else:
+    var
+      res = Vector2()
+      caret_pos = 0
+      current_pos = 0
+    for line in self.text.splitLines():  # get text height
+      var x: float = 0f
+      current_pos = 0
+      res.y += self.spacing + self.size
+      for c in line.chars:
+        x += self.font.glutBitmapWidth(c.c.int).float
+        inc caret_pos
+        inc current_pos
+        if res.y >= pos.y:
+          if current_pos < line.len() and x <= pos.x:
+            continue
+          return caret_pos
+      inc caret_pos
+      if x > res.x:
+        res.x = x
+
+
+method getCharUnderMouse*(self: RichEditTextPtr): ColorCharRef {.base.} =
+  ## Returns char under mouse
+  return self.text[self.getCharPositionUnderMouse()]
+
+
+method getWordPositionUnderMouse*(self: RichEditTextPtr): tuple[startpos, endpos: int] {.base.} =
+  ## Returns words under mouse.
+  ## Returns (-1, -1), if under mouse no founds words.
+  var caret = self.getCharPositionUnderMouse()
+  if caret == self.text.len():
+    return (-1, -1)
+
+  if self.text.len() > 0 and self.text[caret].c != ' ':
+    # Left
+    var i = caret
+    while self.text[i].c != ' ':
+      dec i
+      if i < 0:
+        break
+    if i > 0:
+      if self.text[i].c == ' ':
+        i += 1
+      result.startpos = i
+    else:
+      result.startpos = 0
+    # Right
+    i = caret
+    while self.text[i].c != ' ':
+      inc i
+      if i > self.text.len()-1:
+        break
+    if i < self.text.len():
+      if self.text[i].c == ' ':
+        i -= 1
+      result.endpos = i
+    else:
+      result.endpos = self.text.len()-1
+  else:
+    return (-1, -1)
+
+
+method getWordUnderMouse*(self: RichEditTextPtr): ColorTextRef {.base.} =
+  ## Returns words under mouse.
+  let (s, e) = self.getWordPositionUnderMouse()
+  if self.text.len() > 0:
+    return self.text[s..e]
+
+
 method draw*(self: RichEditTextPtr, w, h: GLfloat) =
   ## This uses in the `window.nim`.
   self.calcGlobalPosition()
@@ -147,7 +225,7 @@ method draw*(self: RichEditTextPtr, w, h: GLfloat) =
         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)
+          glRectf(tx, ty-1, tx+cw, ty-2)
         self.font.glutBitmapCharacter(c.c.int)  # render char
 
         inc char_num
@@ -166,6 +244,7 @@ method draw*(self: RichEditTextPtr, w, h: GLfloat) =
   if self.pressed:
     self.press(last_event.x, last_event.y)
 
+
 method duplicate*(self: RichEditTextPtr, obj: var RichEditTextObj): RichEditTextPtr {.base.} =
   ## Duplicates RichEditText and create a new RichEditText pointer.
   obj = self[]
@@ -182,36 +261,7 @@ method handle*(self: RichEditTextPtr, event: InputEvent, mouse_on: var NodePtr)
     glutSetCursor(GLUT_CURSOR_LEFT_ARROW)
 
   if event.kind == MOUSE and event.pressed:
-    let
-      size = self.getTextSize()
-      pos = Vector2Ref(x: event.x, y: event.y) - self.global_position
-    if pos.y > size.y:
-      self.caret_position = self.text.len()
-    else:
-      var
-        res = Vector2()
-        caret_pos = 0
-        current_pos = 0
-        stop = false
-      for line in self.text.splitLines():  # get text height
-        var x: float = 0f
-        current_pos = 0
-        res.y += self.spacing + self.size
-        for c in line.chars:
-          x += self.font.glutBitmapWidth(c.c.int).float
-          inc caret_pos
-          inc current_pos
-          if res.y >= pos.y:
-            if current_pos < line.len() and x <= pos.x:
-              continue
-            stop = true
-            self.caret_position = caret_pos
-            break
-        if stop:
-          break
-        inc caret_pos
-        if x > res.x:
-          res.x = x
+    self.caret_position = self.getCharPositionUnderMouse()
 
   if self.focused:
     if event.kind == KEYBOARD:

+ 4 - 0
src/nodesnim/window.nim

@@ -267,6 +267,8 @@ proc Window*(title: cstring, w: cint = 640, h: cint = 360) {.cdecl.} =
 
 proc windowLaunch* =
   ## Start main window loop.
+  when defined(debug):
+    info("launch window ...")
   glutDisplayFunc(display)
   glutIdleFunc(display)
   glutReshapeFunc(reshape)
@@ -281,5 +283,7 @@ proc windowLaunch* =
   if main_scene == nil:
     raise newException(MainSceneNotLoadedError, "Main scene is not indicated!")
   changeScene(main_scene.name)
+  when defined(debug):
+    info("window launched")
   glutMainLoop()
   current_scene.exit()

+ 9 - 0
tests/test19.nim

@@ -20,11 +20,20 @@ label.setSizeAnchor(1, 1)
 label.process =
   proc() =
     label.text.setColor(Color(1f, 1f, 1f))
+    label.text.setUnderline(false)
+
+    # Nim highlight
     var start_position = ($label.text).find("Nim")
     while start_position > -1:
       label.text.setColor(start_position, start_position+2, Color(0xaa99ffff'u32))
       start_position = ($label.text).find("Nim", start_position+2)
 
+    # word underline
+    if label.text.len() > 0:
+      let (s, e) = label.getWordPositionUnderMouse()
+      if s != -1:
+        label.text.setUnderline(s, e, true)
+
 
 addScene(main)
 setMainScene("Main")