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