Selaa lähdekoodia

add `setURL` method

Ethosa 3 vuotta sitten
vanhempi
commit
60d61da478
3 muutettua tiedostoa jossa 53 lisäystä ja 7 poistoa
  1. 24 5
      src/nodesnim/core/font.nim
  2. 26 0
      src/nodesnim/nodescontrol/label.nim
  3. 3 2
      tests/test3.nim

+ 24 - 5
src/nodesnim/core/font.nim

@@ -16,8 +16,9 @@ import
 
 type
   StyleUnicode* = ref object
+    is_url*: bool
     style*: cint
-    c*: string
+    c*, url*: string
     color*: ColorRef
   StyleText* = ref object
     font*: FontPtr
@@ -27,11 +28,15 @@ type
     texture*: GlTextureObj
     chars*: seq[StyleUnicode]
 
+let URL_COLOR = Color(0.45, 0.45, 0.9)
 
-proc schar*(c: string, color: ColorRef = Color(1f, 1f, 1f), style: cint = TTF_STYLE_NORMAL): StyleUnicode =
-  StyleUnicode(c: c, color: color, style: style)
 
-proc stext*(text: string, color: ColorRef = Color(1f, 1f, 1f), style: cint = TTF_STYLE_NORMAL): StyleText =
+proc schar*(c: string, color: ColorRef = Color(1f, 1f, 1f),
+            style: cint = TTF_STYLE_NORMAL, is_url: bool = false): StyleUnicode =
+  StyleUnicode(c: c, color: color, style: style, is_url: is_url, url: "")
+
+proc stext*(text: string, color: ColorRef = Color(1f, 1f, 1f),
+            style: cint = TTF_STYLE_NORMAL): StyleText =
   result = StyleText(texture: GlTextureObj(size: Vector2()), spacing: 2, max_lines: -1)
   for i in text.utf8():
     result.chars.add(schar(i, color, style))
@@ -142,6 +147,12 @@ styleFunc(setItalic, TTF_STYLE_ITALIC)
 styleFunc(setUnderline, TTF_STYLE_UNDERLINE)
 styleFunc(setStrikethrough, TTF_STYLE_STRIKETHROUGH)
 
+proc setURL*(text: StyleText, s, e: int, url: string) =
+  for i in s..e:
+    text.chars[i].is_url = true
+    text.chars[i].url = url
+    text.chars[i].color = URL_COLOR
+
 proc setFont*(text: StyleText, font: cstring, size: cint) =
   text.font = openFont(font, size)
 
@@ -255,6 +266,14 @@ proc getPosUnderPoint*(text: StyleText, global_pos, text_pos: Vector2Obj,
     if position.x == -1f:
       result = 0
 
+proc getCharUnderPoint*(text: StyleText, global_pos, text_pos: Vector2Obj,
+                        text_align: AnchorObj = Anchor(0, 0, 0, 0)): tuple[c: StyleUnicode, pos: uint32] =
+  let pos = text.getPosUnderPoint(global_pos, text_pos, text_align)
+  if pos > 0:
+    (c: text.chars[pos-1], pos: pos-1)
+  else:
+    (c: text.chars[pos], pos: pos)
+
 
 # ------ Render ------ #
 
@@ -273,7 +292,7 @@ proc renderSurface*(text: StyleText, align: AnchorObj): SurfacePtr =
       textsize = text.getTextSize()
     var
       surface = createRGBSurface(
-        0, textsize.x.cint, textsize.y.cint, 32,
+        0, textsize.x.cint + 8, textsize.y.cint, 32,
         0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000u32)
       y: cint = 0
       w: cint

+ 26 - 0
src/nodesnim/nodescontrol/label.nim

@@ -19,6 +19,7 @@ import
 
   ../nodes/node,
   ../nodes/canvas,
+  browsers,
   control
 
 
@@ -61,6 +62,31 @@ method duplicate*(self: LabelRef): LabelRef {.base.} =
 method getText*(self: LabelRef): string {.base.} =
   $self.text
 
+method handle*(self: LabelRef, event: InputEvent, mouse_on: var NodeRef) =
+  ## Handles user input. Thi uses in the `window.nim`.
+  procCall self.ControlRef.handle(event, mouse_on)
+
+  if event.kind in [MOUSE, MOTION]:
+    let (c, pos) = self.text.getCharUnderPoint(
+      self.getGlobalMousePosition(), self.global_position + self.rect_size/2 - self.text.getTextSize()/2,
+      self.text_align)
+
+    if c.is_url:
+      var (i, j) = (pos.int, pos.int)
+      while i - 1 > 0 and self.text.chars[i - 1].is_url:
+        dec i
+      while j + 1 < self.text.len and self.text.chars[j + 1].is_url:
+        inc j
+      self.text.setUnderline(i, j, true)
+      self.text.rendered = false
+      if last_event.pressed and last_event.kind == MOUSE:
+        openDefaultBrowser(c.url)
+    else:
+      for i in self.text.chars:
+        if i.is_url:
+          i.setUnderline(false)
+      self.text.rendered = false
+
 method setText*(self: LabelRef, text: string, save_properties: bool = false) {.base.} =
   ## Changes text.
   ##

+ 3 - 2
tests/test3.nim

@@ -104,9 +104,10 @@ suite "Work with Control nodes.":
   test "Label test":
     build:
       - Label label:
-        call setText("hello,\nworld!")
+        call setText("hello,\nworld!\n    VK!")
         call move(0, 40)
     label.text.setColor(6, 12, Color("#664fff"))
+    label.text.setURL(18, 19, "https://vk.com")
     label.text.setUnderline(0, 2, true)
     label.text.setStrikethrough(1, 3, true)
     label.text.setItalic(0, true)
@@ -197,7 +198,7 @@ suite "Work with Control nodes.":
   test "EditText test":
     build:
       - EditText edit:
-        call move(0, 100)
+        call move(0, 150)
     getSceneByName("main").addChild(edit)