import pygame as pg from pygame import Rect from piece_table import PieceTable import os import json import sys import time import copy from dataclasses import dataclass class Cursor: def __init__(self, row, col): self.row: int = 0 self.col: int = 0 self.want_col: int = 0 def pos(self): return (self.row, self.col) class Row: def __init__(self, text): self.text = PieceTable(text) self.length = len(text) class Buffer: def __init__(self, raw_text): pass oswinx, oswiny = 1940,50 os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (oswinx,oswiny) clock = pg.time.Clock() pg.init() pg.font.init() text_renderer = pg.font.SysFont('JetBrains Mono', 14) screen = pg.display.set_mode((900, 900), pg.RESIZABLE) pg.key.set_repeat(240, 10) rows = [] cursor = Cursor(0, 0) line_height = 20 char_width = 8 with open('../gux/test.c', 'r', encoding='utf-8') as f: text = f.read() for line in text.split('\n'): rows.append(Row(line)) # print(current_buffer[120:125]) f.close() def draw_cursor(): rect = Rect(cursor.col * char_width, cursor.row * line_height, 3, line_height) pg.draw.rect(screen, "black", rect, width=2) if __name__ == '__main__': running = True # print(current_buffer.display()) frame_count = 0 cursor_flash = 0 cursor_on = True while running: dt = clock.tick(120) / 1000.0 screen.fill('white') frame_count += 1 for event in pg.event.get(): if event.type == pg.QUIT: running = False if event.type == pg.KEYDOWN: # print(frame_count, event.unicode, pg.key.name(event.key), event.mod, end="") # print("") # print(event.mod) cursor_on = True cursor_flash = 0 row = rows[cursor.row] if event.key == pg.K_RETURN: if cursor.col < row.length: remainder = row.length - cursor.col line = row.text.string_at(cursor.col, remainder) row.text.delete(cursor.col, remainder) row.length -= remainder else: line = "" rows.insert(cursor.row+1, Row(str(line))) cursor.row += 1 # Eventually when we need to be indentation aware cursor.col = 0 cursor.want_col = 0 elif event.key == pg.K_BACKSPACE: if cursor.pos() != (0,0): if cursor.col == 0: row = rows.pop(cursor.row) cursor.row -= 1 above_row = rows[cursor.row] above_row.text.insert(row.text.get_text(), above_row.length) cursor.col = above_row.length cursor.want_col = cursor.col above_row.length += row.length else: row.text.delete(cursor.col - 1, 1) row.length -= 1 cursor.col = max(0, cursor.col - 1) cursor.want_col = cursor.col elif event.key == pg.K_DELETE: if cursor.col >= rows[cursor.row].length: if cursor.row < len(rows) - 1: below_row = rows.pop(cursor.row+1) if below_row.length > 0: row.text.insert(below_row.text.get_text(), row.length) row.length += below_row.length cursor.want_col = cursor.col else: if row.length >= 1: row.text.delete(cursor.col, 1) row.length -= 1 cursor.want_col = cursor.col elif event.key == pg.K_LEFT: if cursor.col == 0: if cursor.row > 0: cursor.col = rows[cursor.row-1].length cursor.want_col = cursor.col cursor.row -= 1 else: cursor.col = max(0, cursor.col - 1) cursor.want_col = cursor.col elif event.key == pg.K_RIGHT: if cursor.col == rows[cursor.row].length: if cursor.row < len(rows): cursor.col = 0 cursor.want_col = cursor.col cursor.row += 1 else: cursor.col = min(rows[cursor.row].length, cursor.col + 1) cursor.want_col = cursor.col elif event.key == pg.K_UP: cursor.row = max(0, cursor.row - 1) cursor.col = min(cursor.want_col, rows[cursor.row].length) elif event.key == pg.K_DOWN: cursor.row = min(len(rows) - 1, cursor.row + 1) cursor.col = min(cursor.want_col, rows[cursor.row].length) elif event.key == pg.K_SPACE: row.text.insert(u' ', cursor.col) row.length += 1 cursor.col += 1 cursor.want_col = cursor.col elif event.key >= 33 and event.key <= 126 and event.mod < 2: row.text.insert(event.unicode, cursor.col) row.length += 1 cursor.col += 1 cursor.want_col = cursor.col elif event.mod == 64: # Right Ctrl if event.key == pg.K_e: cursor.col = rows[cursor.row].length cursor.want_col = cursor.col if event.key == pg.K_a: cursor.col = 0 cursor.want_col = cursor.col for i,row in enumerate(rows): render = text_renderer.render(row.text.get_text(), True, 'black') screen.blit(render, (0, i * line_height)) if cursor_on and cursor_flash < 0.5: draw_cursor() elif cursor_on: cursor_on = False cursor_flash = 0 elif not cursor_on and cursor_flash > 0.5: cursor_on = True cursor_flash = 0 cursor_flash += dt pg.display.flip()