diff --git a/Cargo.lock b/Cargo.lock
index c131323..2dbafa8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1565,6 +1565,24 @@ dependencies = [
[[package]]
name = "ironforce_degeon"
version = "0.1.0"
+dependencies = [
+ "base64",
+ "chrono",
+ "core-error",
+ "futures",
+ "iced",
+ "iced_native",
+ "include_optional",
+ "rand",
+ "rand_os",
+ "rayon",
+ "rsa",
+ "serde",
+ "serde_cbor",
+ "serde_json",
+ "sha2",
+ "spin 0.9.2",
+]
[[package]]
name = "itoa"
diff --git a/Cargo.toml b/Cargo.toml
index eb91217..64cf5b4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,3 +12,22 @@ members = ["degeon", "degeon_core", "ironforce"]
name = "ironforce"
path = "ironforce/src/lib.rs"
+[dependencies]
+rand_os = "*"
+# x25519-dalek = "0.6.0"
+# ed25519-dalek = { version = "1.0", features = ["serde"] }
+sha2 = "0.8.1"
+rand = "*"
+rsa = { version = "0.5", features = ["serde"] }
+serde = { version = "1.0", features = ["derive", "alloc"], default-features = false }
+rayon = { version = "1.5.1", optional = true }
+core-error = "0.0.1-rc4"
+serde_cbor = "0.11.2"
+serde_json = "1.0.72"
+spin = "0.9.2"
+base64 = "0.13.0"
+include_optional = "1.0.1"
+iced = { version = "0.3.0", features = ["image"] }
+futures = "0.3.18"
+iced_native = "0.4.0"
+chrono = "0.4.19"
diff --git a/degeon_py/degeon_core.so b/degeon_py/degeon_core.so
index 211fda0..a0ed37e 100755
Binary files a/degeon_py/degeon_core.so and b/degeon_py/degeon_core.so differ
diff --git a/degeon_py/input_field.py b/degeon_py/input_field.py
index dd9cf54..3828d9d 100644
--- a/degeon_py/input_field.py
+++ b/degeon_py/input_field.py
@@ -1,8 +1,10 @@
+import time
import typing
import pygame
from config import font, MESSAGE_HEIGHT, WIDTH, CHAT_SELECTOR_WIDTH, HEIGHT, WHITE, DARKER_BLUE, GREY
+from utils import render_text
from dataclasses import dataclass
@@ -39,14 +41,7 @@ class TextField:
)
)
if self.value:
- message_text: pygame.Surface = font.render(self.value, True, WHITE)
- surface.blit(
- message_text,
- (
- 40, # or, if we want to center, `(self.width - message_text.get_width()) // 2,`
- (self.height - message_text.get_height()) // 2
- )
- )
+ render_text(surface, (10, 10), font, self.value, WHITE, self.cursor_position if time.time() % 1 < 0.5 else None)
return surface
def process_event(self, event: pygame.event.Event):
@@ -69,6 +64,7 @@ class TextField:
elif event.unicode:
self.value = self.value[:self.cursor_position] + event.unicode + self.value[self.cursor_position:]
self.cursor_position += 1
+ self.cursor_position = max(0, min(self.cursor_position, len(self.value)))
def collect(self) -> str:
"""
diff --git a/degeon_py/utils.py b/degeon_py/utils.py
new file mode 100644
index 0000000..b67e581
--- /dev/null
+++ b/degeon_py/utils.py
@@ -0,0 +1,50 @@
+from typing import Optional
+import typing
+
+import pygame
+
+
+def draw_cursor(surface, cur_position, high, c, size=4):
+ pygame.draw.line(surface, c,
+ cur_position,
+ (cur_position[0], cur_position[1] + high), size)
+
+
+def get_word_length(ft, word: str):
+ word_surface = ft.render(word, 0, pygame.Color('black'))
+ return word_surface.get_size()
+
+
+def render_text(surface, position: typing.Tuple[int, int], font: pygame.font, text: str, c=pygame.Color('black'),
+ cursor_position: Optional[int] = None):
+ """Render text with hyphenation"""
+
+ if len(text) == 0:
+ return None
+
+ need_cursor = cursor_position is not None
+ lines = [word.split() for word in text.splitlines()]
+ space_size = font.size(' ')[0]
+ max_width, max_height = surface.get_size()
+
+ x, y = position
+ symbols_counter = 0
+ for line in lines:
+ for word in line:
+ w, h = get_word_length(font, word)
+ if w > max_width or h > max_height:
+ raise ValueError("Surface is too small")
+ if x + w >= max_width:
+ x = position[0]
+ y += h
+ surface.blit(font.render(word, 0, c), (x, y))
+ if need_cursor and symbols_counter + len(word) >= cursor_position:
+ # It means that cursor is in this word or after this word
+ cur_coord = (x + get_word_length(font,
+ word[:cursor_position - symbols_counter])[0], y)
+ draw_cursor(surface, cur_coord, h, c)
+ need_cursor = False
+ symbols_counter += len(word) + 1
+ x += w + space_size
+ y += h
+ x = position[0]
diff --git a/images/dependency_graph.svg b/images/dependency_graph.svg
index 6450c54..f1c8d38 100644
--- a/images/dependency_graph.svg
+++ b/images/dependency_graph.svg
@@ -9,6 +9,9 @@
id="svg9118"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
sodipodi:docname="dependency_graph.svg"
+ inkscape:export-filename="/home/ennucore/dev/ironforce/images/dependency_graph.png"
+ inkscape:export-xdpi="1121.49"
+ inkscape:export-ydpi="1121.49"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
diff --git a/images/explanation.svg b/images/explanation.svg
index cccf792..297b11f 100644
--- a/images/explanation.svg
+++ b/images/explanation.svg
@@ -24,11 +24,11 @@
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
- inkscape:zoom="0.42190593"
- inkscape:cx="117.32473"
- inkscape:cy="387.52714"
+ inkscape:zoom="0.99504919"
+ inkscape:cx="558.26386"
+ inkscape:cy="397.46779"
inkscape:window-width="1920"
- inkscape:window-height="1036"
+ inkscape:window-height="1008"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
@@ -193,19 +193,19 @@
inkscape:export-ydpi="1121.49">keys
+ id="tspan6402">keys
messages
+ id="tspan6404">messages
transport
+ id="tspan6406">transport
tunnels
+ id="tspan6408">tunnels
Messages are collected
+ id="tspan6410">Messages are collected
into a queue
+ id="tspan6414">into a queue
in another thread
+ id="tspan6418">in another thread