Selaa lähdekoodia

s,all optimize.

Ethosa 3 vuotta sitten
vanhempi
commit
9402801082

+ 2 - 1
src/nodesnim/core/font.nim

@@ -137,7 +137,8 @@ styleFunc(setItalic, TTF_STYLE_ITALIC)
 styleFunc(setUnderline, TTF_STYLE_UNDERLINE)
 styleFunc(setStrikethrough, TTF_STYLE_STRIKETHROUGH)
 
-proc setURL*(text: StyleText, s, e: int, url: string) =
+proc setURL*(text: StyleText, s, e: int,
+             url: string, color: ColorRef = URL_COLOR) =
   for i in s..e:
     text.chars[i].is_url = true
     text.chars[i].url = url

+ 29 - 31
src/nodesnim/core/polygon2.nim

@@ -8,105 +8,103 @@ import
 
 
 type
-  Polygon2Obj* = object
-    positions*: seq[Vector2Obj]
-  Polygon2Ref* = ref Polygon2Obj
+  Polygon2Obj* = seq[Vector2Obj]
 
 
-proc Polygon2*(pnts: varargs[Vector2Obj]): Polygon2Ref =
+proc Polygon2*(pnts: varargs[Vector2Obj]): Polygon2Obj =
   ## Creates a new Polygon2 object.
   ##
   ## Arguments:
   ## - `pnts` is a points for the Polygon. points count should be more than 2.
   if pnts.len() < 3:
     return
-  result = Polygon2Ref(positions: @[])
+  result = @[]
   for i in pnts:
-    result.positions.add(i)
+    result.add(i)
 
-proc Polygon2*(pnts: seq[Vector2Obj]): Polygon2Ref =
+proc Polygon2*(pnts: var seq[Vector2Obj]): Polygon2Obj =
   ## Creates a new Polygon2 object.
   ##
   ## Arguments:
   ## - `pnts` is a points for the Polygon. points count should be more than 2.
   if pnts.len() < 3:
     return
-  result = Polygon2Ref(positions: pnts)
+  result = pnts[0..^1]
 
 
-proc contains*(self: Polygon2Ref, x, y: float): bool =
+proc contains*(self: Polygon2Obj, x, y: float): bool =
   ## Returns true, if point `x`, `y` in the Polygon2.
   result = false
   var next = 1
-  let length = self.positions.len()
+  let length = self.len
 
   for i in 0..<length:
     inc next
     if next == length: next = 0
     let
-      a = self.positions[i]
-      b = self.positions[next]
+      a = self[i]
+      b = self[next]
     if ((a.y >= y and b.y < y) or (a.y < y and b.y >= y)) and (x < (b.x-a.x)*(y-a.y) / (b.y-a.y)+a.x):
       result = not result
 
-proc contains*(self: Polygon2Ref, vec2: Vector2Obj): bool {.inline.} =
+proc contains*(self: Polygon2Obj, vec2: Vector2Obj): bool {.inline.} =
   ## Returns true, if point `vec2` in the Polygon2.
   self.contains(vec2.x, vec2.y)
 
 
-proc intersects*(self, other: Polygon2Ref): bool =
+proc intersects*(self, other: Polygon2Obj): bool =
   ## Returns true, if two polygons intersect.
   let
-    length = self.positions.len()
-    otherlength = other.positions.len()
+    length = self.len
+    otherlength = other.len
   var next = 0
 
   for i in 0..<length:
     inc next
     if next == length: next = 0
     let
-      a = self.positions[i]
-      b = self.positions[next]
+      a = self[i]
+      b = self[next]
 
     var othernext = 0
     for i in 0..<otherlength:
       inc othernext
       if othernext == otherlength: othernext = 0
       let
-        c = other.positions[i]
-        d = other.positions[othernext]
+        c = other[i]
+        d = other[othernext]
       if intersects(a, b, c, d):
         return true
 
-proc intersects*(self: Polygon2Ref, r: Rect2Obj): bool =
+proc intersects*(self: Polygon2Obj, r: Rect2Obj): bool =
   ## Returns true, if rect intersect with polygon.
   var next = 1
-  let length = self.positions.len()
+  let length = self.len
 
   for i in 0..<length:
     inc next
     if next == length: next = 0
     let
-      a = self.positions[i]
-      b = self.positions[next]
+      a = self[i]
+      b = self[next]
     if r.contains(a, b):
       return true
 
-proc intersects*(self: Polygon2Ref, circle: CircleObj): bool =
+proc intersects*(self: Polygon2Obj, circle: CircleObj): bool =
   ## Returns true, if circle intersect with polygon.
   var next = 1
-  let length = self.positions.len()
+  let length = self.len
 
   for i in 0..<length:
     inc next
     if next == length: next = 0
     let
-      a = self.positions[i]
-      b = self.positions[next]
+      a = self[i]
+      b = self[next]
     if circle.contains(a, b):
       return true
 
-proc move*(self: Polygon2Ref, vec2: Vector2Obj) =
+proc move*(self: var Polygon2Obj, vec2: Vector2Obj) =
   ## Moves polygon.
-  for i in 0..self.positions.high:
-    self.positions[i] += vec2
+  for i in 0..self.high:
+    self[i] += vec2

+ 9 - 7
src/nodesnim/core/scene_builder.nim

@@ -80,15 +80,17 @@ proc addNode(level: var seq[NimNode], code: NimNode): NimNode {.compileTime.} =
 macro build*(code: untyped): untyped =
   ## Builds nodes with YML-like syntax.
   ##
-  ## Example:
+  ## ## Examples
   ## .. code-block:: nim
   ##
-  ##   build:
-  ##     - Scene scene:
-  ##       - Node test_node
-  ##       - Label text:
-  ##         call setText("Hello, world!")
-  ##       - Button btn(call setText(""))
+  ##    build:
+  ##      - Scene scene:
+  ##        - Node test_node
+  ##        - Label text:
+  ##          call setText("Hello, world!")
+  ##        - Button btn(call setText("")):
+  ##          @onTouch(x, y):
+  ##            echo x, ", ", y
   result = newStmtList()
   var
     current_level: seq[NimNode] = @[]

+ 20 - 8
src/nodesnim/graphics/drawable.nim

@@ -142,6 +142,7 @@ template draw_texture_template*(drawtype, color, function, secondfunc: untyped):
     let q = width / texture_size.x
     texture_size.x *= q
     texture_size.y *= q
+
   if texture_size.y < height:
     let q = height / texture_size.y
     texture_size.x *= q
@@ -152,11 +153,10 @@ template draw_texture_template*(drawtype, color, function, secondfunc: untyped):
   texture_size.x *= q
   texture_size.y *= q
   h /= height/width
-  h -= texture_size.y/2
 
   for i in vertex:
-    glTexCoord2f((-x + i.x - w + texture_size.x) / width,
-                 1f - ((-y + i.y - h + texture_size.y) / texture_size.y))
+    glTexCoord2f((-x + i.x - w + texture_size.x) / texture_size.x,
+                 (y - i.y - h + texture_size.y) / texture_size.y)
     glVertex2f(i.x, i.y)
 
   glEnd()
@@ -211,14 +211,14 @@ method setColor*(self: DrawableRef, color: ColorRef) {.base.} =
   self.background_color = color
 
 method setCornerRadius*(self: DrawableRef, radius: float) {.base.} =
-  ## Changes corner radius.
+  ## Changes corners radius.
   ##
   ## Arguments:
   ## - `radius` is a new corner radius.
   self.border_radius = [radius, radius, radius, radius]
 
 method setCornerRadius*(self: DrawableRef, r1, r2, r3, r4: float) {.base.} =
-  ## Changes corner radius.
+  ## Changes corners radius.
   ##
   ## Arguments:
   ## - `r1` is a new left-top radius.
@@ -228,14 +228,14 @@ method setCornerRadius*(self: DrawableRef, r1, r2, r3, r4: float) {.base.} =
   self.border_radius = [r1, r2, r3, r4]
 
 method setCornerDetail*(self: DrawableRef, detail: int) {.base.} =
-  ## Changes corner detail.
+  ## Changes corners details.
   ##
   ## Arguments:
   ## - `detail` is a new corner detail.
   self.border_detail = [detail, detail, detail, detail]
 
 method setCornerDetail*(self: DrawableRef, d1, d2, d3, d4: int) {.base.} =
-  ## Changes corner detail.
+  ## Changes corners details.
   ##
   ## Arguments:
   ## - `d1` is a new left-top detail.
@@ -255,7 +255,19 @@ method setShadowOffset*(self: DrawableRef, offset: Vector2Obj) {.base.} =
 
 
 method setStyle*(self: DrawableRef, s: StyleSheetRef) {.base.} =
-  ## Sets a new stylesheet.
+  ## Sets new stylesheet.
+  ##
+  ## Styles:
+  ## - `background-color` - `rgb(1, 1, 1)`; `rgba(1, 1, 1, 1)`; `#ffef`.
+  ## - `background-image` - `"assets/image.jpg".
+  ## - `background` - the same as `background-image` and `background-color`.
+  ## - `border-color` - the same as `background-color`.
+  ## - `border-width` - `0`; `8`.
+  ## - `border-detail` - corners details. `8`; `8 8 8 8`.
+  ## - `border-radius` - corners radius. same as `border-detail`.
+  ## - `border` - corners radius and border color. `8 #ffef`.
+  ## - `shadow` - enables shadow. `true`; `yes`; `on`; `off`; `no`; `false`.
+  ## - `shadow-offset` - XY shadow offset. `3`; `5 10`.
   for i in s.dict:
     var matches: array[20, string]
     case i.key

+ 10 - 5
src/nodesnim/nodes/node.nim

@@ -32,15 +32,20 @@ type
   NodeRef* = ref NodeObj
 
 
+var
+  handler_default = proc(self: NodeRef) = discard
+  event_handler_default = proc(self: NodeRef, event: InputEvent) = discard
+
+
 template nodepattern*(nodetype: untyped): untyped =
   ## This used in childs of the NodeObj.
   result = `nodetype`(
     name: name, children: @[],
-    on_ready: proc(self: NodeRef) = discard,
-    on_process: proc(self: NodeRef) = discard,
-    on_input: proc(self: NodeRef, event: InputEvent) = discard,
-    on_enter: proc(self: NodeRef) = discard,
-    on_exit: proc(self: NodeRef) = discard,
+    on_ready: handler_default,
+    on_process: handler_default,
+    on_input: event_handler_default,
+    on_enter: handler_default,
+    on_exit: handler_default,
     is_ready: false, pausemode: INHERIT, visibility: VISIBLE
   )
   result.type_of_node = NODE_TYPE_DEFAULT

+ 6 - 2
src/nodesnim/nodescontrol/button.nim

@@ -19,6 +19,7 @@ import
 
 
 type
+  ButtonTouchHandler* = proc(self: ButtonRef, x, y: float)
   ButtonObj* = object of LabelObj
     button_mask*: cint  ## Mask for handle clicks
     action_mask*: cint  ## BUTTON_RELEASE or BUTTON_CLICK.
@@ -27,9 +28,11 @@ type
     hover_background*: DrawableRef   ## color, when button hovered.
     press_background*: DrawableRef   ## color, when button pressed.
 
-    on_touch*: proc(self: ButtonRef, x, y: float): void  ## This called, when user clicks on button.
+    on_touch*: ButtonTouchHandler ## This called, when user clicks on button.
   ButtonRef* = ref ButtonObj
 
+let touch_handler*: ButtonTouchHandler = proc(self: ButtonRef, x, y: float) = discard
+
 
 proc Button*(name: string = "Button"): ButtonRef =
   ## Creates a new Button node.
@@ -52,7 +55,8 @@ proc Button*(name: string = "Button"): ButtonRef =
   result.normal_background.setColor(Color(0x444444ff))
   result.hover_background.setColor(Color(0x505050ff))
   result.press_background.setColor(Color(0x595959ff))
-  result.on_touch = proc(self: ButtonRef, x, y: float) = discard
+  result.on_touch = touch_handler
+  result.on_text_changed = text_changed_handler
   result.kind = BUTTON_NODE
 
 

+ 6 - 2
src/nodesnim/nodescontrol/checkbox.nim

@@ -18,13 +18,17 @@ import
 
 
 type
+  ToggleHandler* = proc(self: CheckBoxRef, toggled: bool)
   CheckBoxRef* = ref object of ControlRef
     enabled*: bool
 
     box: DrawableRef
     text: LabelRef
 
-    on_toggle*: proc(self: CheckBoxRef, toggled: bool): void  ## This called when switch toggled.
+    on_toggle*: ToggleHandler  ## This called when switch toggled.
+
+let toggle_handler*: ToggleHandler = proc(self: CheckBoxRef, toggled: bool) = discard
+
 
 proc CheckBox*(name: string = "CheckBox"): CheckBoxRef =
   ## Creates a new CheckBox.
@@ -45,7 +49,7 @@ proc CheckBox*(name: string = "CheckBox"): CheckBoxRef =
   result.box.setColor(Color("#444444"))
   result.box.setBorderColor(Color("#555555"))
   result.box.setBorderWidth(1)
-  result.on_toggle = proc(self: CheckBoxRef, toggled: bool) = discard
+  result.on_toggle = toggle_handler
 
 
 method disable*(self: CheckBoxRef) {.base.} =

+ 7 - 2
src/nodesnim/nodescontrol/edittext.nim

@@ -21,6 +21,7 @@ import
 
 
 type
+  EditHandler* = proc(pressed_key: string)
   EditTextRef* = ref object of LabelObj
     is_blink, is_select: bool
     caret*, selectable: bool
@@ -28,11 +29,13 @@ type
     caret_color: ColorRef
     hint*: StyleText
     caret_pos: array[2, uint32]
-    on_edit*: proc(pressed_key: string): void  ## This called when user press any key.
+    on_edit*: EditHandler  ## This called when user press any key.
 
 const
   BLINK_TIME: uint8 = 15
   BLINK_WIDTH: float = 2
+let edit_handler*: EditHandler = proc(k: string) = discard
+
 
 proc EditText*(name: string = "EditText", hint: string = "Edit text ..."): EditTextRef =
   nodepattern(EditTextRef)
@@ -49,8 +52,10 @@ proc EditText*(name: string = "EditText", hint: string = "Edit text ..."): EditT
   result.hint.setColor(Color("#ccc"))
   result.text.setColor(Color("#555"))
   result.text_align = Anchor(0, 0, 0, 0)
-  result.on_edit = proc(key: string) = discard
+  result.on_edit = edit_handler
+  result.on_text_changed = text_changed_handler
   result.kind = EDIT_TEXT_NODE
+  
   if result.text.chars.len() > result.hint.chars.len():
     result.rect_min_size = result.text.getTextSize()
   else:

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

@@ -24,11 +24,15 @@ import
 
 
 type
+  TextChangedHandler* = proc(self: LabelRef, text: string)
   LabelObj* = object of ControlRef
+    on_text_changed*: TextChangedHandler
     text_align*: AnchorObj
     text*: StyleText
   LabelRef* = ref LabelObj
 
+let text_changed_handler*: TextChangedHandler = proc(self: LabelRef, text: string) = discard
+
 
 proc Label*(name: string = "Label"): LabelRef =
   ## Creates a new Label.
@@ -43,6 +47,7 @@ proc Label*(name: string = "Label"): LabelRef =
   result.rect_size.y = 40
   result.text = stext""
   result.text_align = Anchor(0, 0, 0, 0)
+  result.on_text_changed = text_changed_handler
   result.kind = LABEL_NODE
 
 
@@ -114,6 +119,7 @@ method setText*(self: LabelRef, text: string, save_properties: bool = false) {.b
   self.rect_min_size = self.text.getTextSize()
   self.resize(self.rect_size.x, self.rect_size.y, true)
   self.text.rendered = false
+  self.on_text_changed(self, text)
 
 method setTextAlign*(self: LabelRef, x1, y1, x2, y2: float) {.base.} =
   ## Changes text alignment.
@@ -152,6 +158,11 @@ method setTextFont*(self: LabelRef, font: FontPtr) {.base.} =
   self.text.rendered = false
 
 method setStyle*(self: LabelRef, s: StyleSheetRef) =
+  ## Changes Label stylesheet.
+  ##
+  ## Styles:
+  ## - `text-align` - text alignment. `0.5`; `1 0 1 0`.
+  ## - `color` - text color. `#ffef`; `rgba(1, 1, 1, 1)`; `rgb(1, 1, 1)`.
   procCall self.ControlRef.setStyle(s)
   self.text.rendered = false
 

+ 5 - 2
src/nodesnim/nodescontrol/slider.nim

@@ -16,15 +16,18 @@ import
 
 
 type
+  SliderChangedHandler* = proc(self: SliderRef, new_value: uint)
   SliderObj* = object of ControlRef
     slider_type*: SliderType
     max_value*, value*: uint
     progress_color*: ColorRef
     thumb*: DrawableRef
 
-    on_changed*: proc(self: SliderRef, new_value: uint): void
+    on_changed*: SliderChangedHandler
   SliderRef* = ref SliderObj
 
+let slider_changed_handler*: SliderChangedHandler =
+    proc(self: SliderRef, new_value: uint) = discard
 
 proc Slider*(name: string = "Slider"): SliderRef =
   ## Creates a new Slider.
@@ -44,7 +47,7 @@ proc Slider*(name: string = "Slider"): SliderRef =
   result.progress_color = Color(0.5, 0.5, 0.5)
   result.max_value = 100
   result.value = 0
-  result.on_changed = proc(self: SliderRef, v: uint) = discard
+  result.on_changed = slider_changed_handler
   result.kind = SLIDER_NODE
 
 

+ 5 - 2
src/nodesnim/nodescontrol/switch.nim

@@ -15,14 +15,17 @@ import
 
 
 type
+  SwitchHandler* = proc(self: SwitchRef, toggled: bool)
   SwitchObj* = object of ControlRef
     value*: bool
     color_enable*, color_disable*: ColorRef
     back_enable*, back_disable*: ColorRef
 
-    on_switch*: proc(self: SwitchRef, toggled: bool): void  ## This called when switch toggled.
+    on_switch*: SwitchHandler  ## This called when switch toggled.
   SwitchRef* = ref SwitchObj
 
+let switch_handler*: SwitchHandler = proc(self: SwitchRef, toggled: bool) = discard
+
 
 proc Switch*(name: string = "Switch"): SwitchRef =
   ## Creates a new Switch.
@@ -40,7 +43,7 @@ proc Switch*(name: string = "Switch"): SwitchRef =
   result.value = false
   result.rect_size.x = 50
   result.rect_size.y = 20
-  result.on_switch = proc(self: SwitchRef, toggled: bool) = discard
+  result.on_switch = switch_handler
   result.kind = COLOR_RECT_NODE
 
 

+ 7 - 2
src/nodesnim/nodescontrol/texture_button.nim

@@ -19,6 +19,7 @@ import
 
 
 type
+  TextureButtonTouchHandler* = proc(self: TextureButtonRef, x, y: float)
   TextureButtonObj* = object of LabelObj
     button_mask*: cint  ## Mask for handle clicks
     action_mask*: cint  ## BUTTON_RELEASE or BUTTON_CLICK.
@@ -27,9 +28,12 @@ type
     hover_background_texture*: GlTextureObj   ## texture, when button hovered.
     press_background_texture*: GlTextureObj   ## texture, when button pressed.
 
-    on_touch*: proc(self: TextureButtonRef, x, y: float): void  ## This called, when user clicks on button.
+    on_touch*: TextureButtonTouchHandler  ## This called, when user clicks on button.
   TextureButtonRef* = ref TextureButtonObj
 
+let texture_btn_touch_handler*: TextureButtonTouchHandler =
+    proc(self: TextureButtonRef, x, y: float) = discard
+
 
 proc TextureButton*(name: string = "TextureButton"): TextureButtonRef =
   ## Creates a new TextureButton node.
@@ -49,7 +53,8 @@ proc TextureButton*(name: string = "TextureButton"): TextureButtonRef =
   result.normal_background_texture = GlTextureObj()
   result.hover_background_texture = GlTextureObj()
   result.press_background_texture = GlTextureObj()
-  result.on_touch = proc(self: TextureButtonRef, x, y: float) = discard
+  result.on_touch = texture_btn_touch_handler
+  result.on_text_changed = text_changed_handler
   result.kind = TEXTURE_BUTTON_NODE
 
 

+ 15 - 0
tests/test5.nim

@@ -72,5 +72,20 @@ suite "Work with graphics.":
     getSceneByName("main").addChild(ctrl2)
 
 
+  test "Image background":
+    build:
+      - Control ctrl1:
+        call setAnchor(1, 0, 1, 0)
+        call setSizeAnchor(0.2, 0.2)
+
+    ctrl1.background.setTexture(load("assets/anim/2.jpg"))
+    ctrl1.background.setCornerRadius(25)
+    ctrl1.background.setCornerDetail(8)
+    ctrl1.background.enableShadow(true)
+    ctrl1.background.setShadowOffset(Vector2(0, 8))
+
+    getSceneByName("main").addChild(ctrl1)
+
+
   test "Launch window":
     windowLaunch()