Created
October 8, 2012 23:55
-
-
Save fowlmouth/3855702 to your computer and use it in GitHub Desktop.
lua repl thinger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lua, lualib, lauxlib, sfml, sfml_colors, strutils, sf_gui, json | |
const | |
ScreenW = 800 | |
ScreenH = 600 | |
var | |
window = new_render_window(video_mode(ScreenW, ScreenH, 32), "Lame Lua", sfDefaultStyle) | |
event: TEvent | |
text = newText("herro", guifont, 18) | |
gui = newContainer("luathinger_settings.json") | |
txtarea = PTextArea(gui["input"]) | |
clock = newClock() | |
cursor_sprite = txtarea.cursor_sprite.copy() | |
luaOutput = PTextArea(gui["lua-output"]) | |
proc last*[A](s: var seq[A]): A {.inline.} = | |
return s[high(s)] | |
cursor_sprite.set_outline_color Green | |
gui.set_pack_padding vec2i(4, 4) | |
gui.set_position(vec2f(0, 16 * txtarea.height)) | |
gui.newButton("test 1", onClick = proc(b: PButton) = | |
b.setString("CLICKED!")) | |
gui.newButton("test2", onclick = proc(b: PButton) = | |
b.setString("zomg")) | |
var | |
dbg1 = gui.newButton("##") | |
dbg2 = gui.newButton("##") | |
luaError = gui.newButtonStyled(color = Red) | |
mousePos: TVector2i | |
block: | |
var b1 = gui.newButton("##") | |
b1.updateProc = proc(b: PButton; dt: float) = | |
b.text.setString("@ "& $txtarea.cursor) | |
dbg1.updateProc = proc(b: PButton; dt: float) = | |
b.set_string($mousePos) | |
dbg2.updateProc = proc(b: PButton; dt: float) = | |
b.set_string($txtarea.basepos(mouse_pos)) | |
var | |
notif = gui.newNotifyArea(vec2f(0, ScreenH - 16)) | |
proc postinc(i: var int, by = 1): int = | |
result = i | |
inc(i, by) | |
proc stackdump(L: PState) = | |
var top = L.get_top | |
echo "top is ", top | |
var res = "" | |
for i in 1..top: | |
case luatype(L, i) | |
of TSTRING: | |
res.add($tostring(L, i)) | |
of TBOOLEAN: | |
res.add($toboolean(L, i)) | |
of lua.TNUMBER: | |
res.add($tonumber(L, i)) | |
else: | |
res.add($typename(L, i)) | |
res.add(' ') | |
echo res | |
{.pragma: lua, cdecl.} | |
proc lua_print(L: PState): int {.lua.} = | |
let num_args = L.get_top | |
var res = "" | |
L.get_global "tostring" | |
for i in 1..num_args: | |
L.push_value(-1) | |
L.push_value(i) | |
L.call 1, 1 | |
var s = L.tostring(-1) | |
if s == nil: | |
stackdump(L) | |
break | |
res.add($s) | |
if i < num_args: | |
res.add " " | |
L.pop 1 | |
luaOutput.add_output(res) | |
stackdump(L) | |
return 0 | |
discard """ | |
static int luaB_print (lua_State *L) { | |
int n = lua_gettop(L); /* number of arguments */ | |
int i; | |
lua_getglobal(L, "tostring"); | |
for (i=1; i<=n; i++) { | |
const char *s; | |
lua_pushvalue(L, -1); /* function to be called */ | |
lua_pushvalue(L, i); /* value to print */ | |
lua_call(L, 1, 1); | |
s = lua_tostring(L, -1); /* get result */ | |
if (s == NULL) | |
return luaL_error(L, LUA_QL("tostring") " must return a string to " | |
LUA_QL("print")); | |
if (i>1) fputs("\t", stdout); | |
fputs(s, stdout); | |
lua_pop(L, 1); /* pop result */ | |
} | |
fputs("\n", stdout); | |
return 0; | |
} | |
""" | |
proc lua_listvars(L: PState): int {.cdecl.}= | |
#var ar: PDebug = cast[PDebug](alloc0(sizeof(TDebug))) | |
var ar: TDebug | |
var i = 0 | |
if L.getStack(1, addr ar) == 0: | |
return 0 | |
i = 1 | |
var name: cstring | |
while true: | |
name = getLocal(L, addr ar, postinc(i)) | |
if name.isNil: break | |
luaOutput.add_output("local "& $( i - 1 ) &' '& $name) | |
L.pop(1) | |
return 0 | |
var L = newstate() | |
openlibs(L) | |
for lib in {"print": lua_print, "listvars": lua_listvars}: | |
register(L, cstring(lib[0]), lib[1]) | |
gui.newButton("stackdump", onClick = proc(b: PButton) = | |
stackdump(L)) | |
echo($gui.getposition) | |
window.set_framerate_limit 60 | |
while window.isOpen: | |
let dt = clock.restart.asMilliseconds / 1000 | |
while window.pollEvent(event): | |
case event.kind | |
of evt_closed: | |
window.close() | |
of evt_mousebuttonpressed: | |
if event.mouseButton.button == MouseLeft: | |
gui.click(mousePos) | |
elif event.mouseButton.button == MouseMiddle: | |
var s = "" | |
for line in txtarea.lines: | |
if line != "": | |
s.add(line) | |
s.add "\n" | |
var error = loadbuffer(L, s, s.len(), "line") != 0 or | |
pcall(L, 0, 0, 0) != 0 | |
if error: | |
luaError.setString($toString(L, -1)) | |
stackdump(L) | |
pop(L, 1) | |
notif.add("Button pressed: "& $event.mouseButton.button) | |
of evt_mouse_moved: | |
mouse_pos.x = event.mouseMove.x | |
mouse_pos.y = event.mouseMove.y | |
var | |
base_pos = txtarea.basepos(mouse_pos) | |
cursor_sprite.set_position vec2f( | |
base_pos.x * txtarea.glyphsize.width, | |
base_pos.y * txtarea.glyphsize.height) | |
of evt_key_pressed: | |
txtarea.handle event.key | |
if event.key.code == keyEscape: | |
window.close | |
of evt_text_entered: | |
txtarea.handle event.text | |
else: discard | |
gui.update(dt) | |
window.clear Black | |
window.draw gui | |
window.draw cursor_sprite | |
window.display() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"widgets":{ | |
"handle":{ | |
"type": "handle", | |
"text": "foo", | |
"bg-color": "dpurp", | |
"color": "white", | |
"fontsize": 12}, | |
"input":{ | |
"type": "textgrid", | |
"handle": "handle", | |
"bg-color": "black", | |
"color": "white", | |
"cursor-color": "notus", | |
"tiled-pos": [1,1], | |
"size": [30, 25]}, | |
"lua-output":{ | |
"type": "textgrid", | |
"tiled-pos": [30,1], | |
"bg-color": "dgray", | |
"color": "bizzeige", | |
"handle": "handle"} | |
}, | |
"layout":{ | |
"cursor":{ | |
} | |
}, | |
"colors":{ | |
"black":[0,0,0], | |
"white":[255, 255, 255], | |
"gray":[150,150,150], | |
"dgray":[40, 40, 40], | |
"dgray-a25":[40, 40, 40, 60], | |
"dgreen":[31,112,10], | |
"lgreen":[121,204,60], | |
"bizzeige":[230,213,195], | |
"martha":[172,135,93], | |
"dpurp":[39,10,51], | |
"lpurp":[69,26,62], | |
"notus":[61,123,128], | |
"ganymede":[177,230,209] | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sfml, sfml_colors, json, tables, strutils | |
type | |
PWidget* = ref TWidget | |
TWidget* = object of TObject | |
PClickable* = ref TClickable | |
TClickable* = object of TWidget | |
bounds: TFloatRect | |
hidden: bool | |
PTextLAbel* = ref TTextLabel | |
TTextLabel* = object of TClickable | |
bg*: PRectangleShape | |
text*: PText | |
PButton* = ref TButton | |
TButton* = object of TTextLabel | |
enabled: bool | |
onClick: proc(b: PButton) | |
updateProc*: proc(b: PButton; dt: float) | |
PHandle* = ref THandle | |
THandle* = object of TTextLabel | |
widget: PWidget | |
c: PContainer | |
PackDir = enum | |
PackDown, PackUp, PackLeft, PackRight | |
TMessage* = tuple[ | |
life: float; text: PText] | |
PNotifyArea* = ref TNotifyArea | |
TNotifyArea* = object of TWidget | |
pos: TVector2f | |
layout: PackDir | |
texts: seq[TMessage] | |
lifetime: float | |
PContainer* = ref TContainer | |
TContainer* = object of TClickable | |
widgets*: seq[PWidget] | |
namedWidgets: TTable[string, PWidget] | |
position: TVector2f | |
layout: PackDir | |
pack_pos: TVector2f | |
pack_padding: TVector2i | |
PTextArea* = ref TTextArea | |
TTextArea* = object of TClickable | |
lines*: seq[string] | |
texts*: seq[PText] | |
textProto: PText | |
cursor*: TVector2i | |
cursorSprite*: PRectangleShape | |
glyphsize*: TIntRect | |
bg: PRectangleShape | |
height*, width*: int | |
var | |
guiFont* = newFont("LiberationMono-Regular.ttf") | |
method click*(w: PWidget; pos: TVector2i) = nil | |
method setPosition*(w: PWidget; val: TVector2f) = nil | |
method getPosition*(w: PWidget): TVector2f = nil | |
template unless(cond: expr; body: stmt): stmt = | |
if not(cond): | |
body | |
proc basePos*(t: PTextArea; vec: TVector2i): TVector2i = | |
result.x = ((vec.x - (vec.x mod t.glyphsize.width)) / t.glyphsize.width).int32 | |
result.y = ((vec.y - (vec.y mod t.glyphsize.height))/ t.glyphsize.height).int32 | |
method set_pack_padding*(c: PContainer; val: TVector2i) = | |
c.pack_padding = val | |
method click*(b: PButton; pos: TVector2i) = | |
if b.bounds.contains(pos.x.float, pos.y.float) and not b.onClick.isNil: | |
b.onClick(b) | |
method click*(t: PTextArea; pos: TVector2i) = | |
discard """echo repr(evt) | |
echo repr(t.basepos(evt.mouseButton.x, evt.mouseButton.y))""" | |
if t.bounds.contains(pos.x, pos.y): | |
let bp = t.basepos(pos - vec2i(t.text_proto.get_position)) | |
if bp.y < t.height: t.cursor.y = bp.y | |
if bp.x < t.width: | |
t.cursor.x = bp.x | |
if t.cursor.x > t.lines[t.cursor.y].len: | |
t.cursor.x = t.lines[t.cursor.y].len.cint | |
echo($t.cursor) | |
method click*(h: PHandle; pos: TVector2i) = | |
if not h.widget.isNil: | |
h.widget.click pos | |
method click*(c: PContainer; pos: TVector2i) = | |
for w in c.widgets: | |
w.click(pos) | |
proc pack*[A: PText|PRectangleShape|PSprite|PCircleShape](c: PContainer; obj: A) = | |
setPosition(obj, c.position + c.pack_pos) | |
case c.layout | |
of pack_down: | |
c.pack_pos.y += (obj.getLocalBounds.height.cfloat + | |
c.pack_padding.y.cfloat) | |
of pack_up: | |
c.pack_pos.y -= (obj.getLocalBounds.height.cfloat + | |
c.pack_padding.y.cfloat) | |
of pack_left: | |
c.pack_pos.x -= (obj.getLocalBounds.width.cfloat + | |
c.pack_padding.x.cfloat) | |
of pack_right: | |
c.pack_pos.x += (obj.getLocalBounds.width.cfloat + | |
c.pack_padding.x.cfloat) | |
proc free*(obj: PNotifyArea) = | |
for i in obj.texts: | |
i.text.destroy() | |
method get_height*(b: PButton): int32 = | |
return b.text.getCharacterSize() | |
method pack_move*(vec: var TVector2f; layout: PackDir; b: PButton) = | |
case layout | |
of pack_down: | |
vec.y += b.getHeight.float | |
of pack_up: | |
vec.y -= b.getHeight.float | |
else: nil | |
proc pack_move*(vec: var TVector2f; layout: PackDir; val: float) = | |
case layout | |
of pack_down: | |
vec.y += val | |
of pack_up: | |
vec.y -= val | |
else: nil | |
method add*(c: PContainer, w: PWidget) = | |
c.widgets.add w | |
method add*(c: PContainer; b: PButton) = | |
##add(c, PWidget(b)) | |
c.widgets.add b | |
proc newNotifyArea*(): PNotifyArea = | |
new(result, free) | |
result.texts = @[] | |
result.layout = pack_up | |
result.lifetime = 1.2 | |
proc newNotifyArea*(c: PContainer; pos: TVector2f): PNotifyArea{.discardable.}= | |
result = newNotifyArea() | |
result.pos = pos | |
c.add result | |
method setPosition*(c: PContainer, val: TVector2f) = | |
c.position = val | |
method getPosition*(c: PContainer): TVector2f = | |
result = c.position | |
method setString*(w: PWidget; str: string) = | |
quit "setString not implemented!" | |
method setString*(L: PTextLabel; str: string) = | |
L.text.setString str | |
let b = L.text.get_local_bounds | |
L.bg.set_size vec2f(b.width, b.height) | |
method add*(n: PNotifyArea; msg: string) = | |
var m: TMessage | |
m.life = n.lifetime | |
m.text = newText(msg, guiFont, 16) | |
n.texts.add(m) | |
method setFillColor*(t: PTextArea; color: TColor) = | |
t.bg.set_fill_color color | |
method setFillColor*(t: PTextLabel; color: TColor) = | |
t.bg.set_fill_color color | |
method setColor*(t: PTextArea; color: TColor) = | |
t.text_proto.set_color color | |
for i in 0..high(t.texts): | |
t.texts[i].set_color color | |
method setColor*(t: PTextLabel; color: TColor) = | |
t.text.set_color color | |
method `[]`*(a: PContainer; b: int): PWidget = | |
return a.widgets[b] | |
method `[]`*(a: PContainer, b: string): PWidget = | |
return a.namedWidgets[b] | |
proc setPosition*(h: PTextLabel; pos: TVector2f) = | |
h.text.setPosition pos | |
h.bg.setPosition pos | |
proc newHandle*(c: PContainer; widget: PWidget; text: string; size: cint): PHandle {.discardable.} = | |
new(result)# free) | |
#init(PButton(result), c, text, nil) | |
result.widget = widget | |
result.text = newText(text, guiFont, size) | |
result.bg = newRectangleShape() | |
result.c = c | |
c.add result | |
proc copy*(h: PHandle; c: PContainer): Phandle {.discardable.} = | |
new(result) | |
result.text = h.text.copy() | |
result.bg = h.bg.copy() | |
result.c = c | |
c.add result | |
proc setup*(handle: PHandle; name: string; pos: TVector2f; widget: PWidget) = | |
handle.widget = widget | |
handle.text.set_string name | |
handle.set_position pos | |
handle.widget.set_position pos + vec2f(0.0, handle.text.getLocalBounds.height) | |
var res = handle.c.widgets.find(widget) | |
if res > -1: | |
handle.c.widgets.del(handle.c.widgets.find(widget)) | |
proc newContainer*(pos = vec2f(0, 0)): PContainer = | |
new(result) | |
result.widgets = @[] | |
result.position = pos | |
proc newTextGrid*(c: PContainer; pos = vec2f(0, 0); width = 80; height = 25): PTextArea | |
type | |
PColorPalette* = ref object | |
colors: seq[tuple[name: string; color: TColor]] | |
idx: int | |
sprite_rect: PRectangleShape | |
var | |
colors: TTable[string, TColor] | |
colorPalette: PColorPalette | |
proc setIndex*(cp: PColorPalette; idx: int) | |
proc newColorPalette(colors: var TTable[string, TColor]): PColorPalette = | |
new(result) | |
result.sprite_rect = newRectangleShape(vec2f(100,100)) | |
result.colors = @[] | |
for name, c in pairs(colors): | |
result.colors.add((name, c)) | |
result.set_index 0 | |
proc setIndex*(cp: PColorPalette; idx: int) = | |
cp.idx = idx | |
cp.sprite_rect.set_fill_color cp.colors[idx].color | |
proc `$`*(a: TColor): string = | |
return "($1, $2, $3, $4)".format(a.r, a.g, a.b, a.a) | |
proc color_f(n: PJsonNode): TColor = | |
result.r = (n[0].fnum * uint8.high.float).uint8 | |
result.g = (n[1].fnum * uint8.high.float).uint8 | |
result.b = (n[2].fnum * uint8.high.float).uint8 | |
if n.len > 3: | |
result.a = (n[3].fnum * uint8.high.float).uint8 | |
else: | |
result.a = uint8.high | |
proc color(n: PJsonNode): TColor = | |
if n.kind == JString and colors.hasKey(n.str): | |
return colors[n.str] | |
assert n.kind == JArray and n.len >= 3 | |
if n[0].kind == JFloat: | |
return color_f(n) | |
result.r = n[0].num.uint8 | |
result.g = n[1].num.uint8 | |
result.b = n[2].num.uint8 | |
if n.len > 3: | |
result.a = n[3].num.uint8 | |
else: | |
result.a = uint8.high | |
proc newContainer*(schema_file: string): PContainer = | |
result = newContainer(vec2f(0,0)) | |
result.namedWidgets = initTable[string, PWidget]() | |
colors = initTable[string, tcolor]() | |
var settings = json.parseFile(schema_file) | |
for name, col in settings["colors"].pairs: | |
colors[name] = color(col) | |
colorPalette = newColorPalette(colors) | |
for name, obj in settings["widgets"].pairs: | |
case obj["type"].str.tolower | |
of "handle": | |
var w = newHandle(result, nil, obj["text"].str, obj["fontsize"].num.cint) | |
if obj.exists_key"bg-color": | |
w.set_fill_color color(obj["bg-color"]) | |
if obj.exists_key"color": | |
w.set_color color(obj["color"]) | |
result.namedWidgets[name] = w | |
of "textgrid": | |
var | |
pos: TVector2f | |
size = vec2i(80, 25) | |
if obj.exists_key"tiled-pos": | |
pos.x = obj["tiled-pos"][0].num.cfloat * 10.cfloat | |
pos.y = obj["tiled-pos"][1].num.cfloat * 16.cfloat | |
if obj.exists_key"size": | |
size.x = obj["size"][0].num.cint | |
size.y = obj["size"][1].num.cint | |
var t = newTextGrid(result, pos, size.x, size.y) | |
if obj.exists_key("handle"): | |
var h = PHandle(result[obj["handle"].str]) | |
if h.widget.isNil: | |
h.setup name, pos, t | |
else: | |
var hh = h.copy(result) | |
hh.setup name, pos, t | |
if obj.exists_key"bg-color": | |
t.set_fill_color(color(obj["bg-color"])) | |
if obj.exists_key"color": | |
t.set_color color(obj["color"]) | |
if obj.exists_key"cursor-color": | |
t.cursor_sprite.set_outline_color color(obj["cursor-color"]) | |
result.namedWidgets[name] = t | |
echo "new textgrid" | |
else: | |
discard | |
proc updateline*(t: PTextArea; idx: int) = | |
t.texts[idx].setPosition( | |
t.text_proto.get_position + vec2f( | |
0.0, t.glyphsize.height.cfloat * idx.cfloat)) | |
method set_string*(b: PButton; s: string) = | |
b.text.set_string s | |
proc free(b: PButton) = | |
b.text.destroy() | |
proc free(h: PHandle) = | |
h.text.destroy() | |
proc init(obj: PButton; c: PContainer; text: string; onClick: proc(b: PButton)) = | |
obj.text = newText(text, guiFont, 16) | |
c.pack(obj.text) | |
obj.bounds = obj.text.get_global_bounds | |
obj.onClick = onClick | |
proc newButton*(c: PContainer; text: string; | |
onClick: proc(b: PButton) = nil): PButton {.discardable.} = | |
new(result, free) | |
init(result, c, text, onclick) | |
c.add result | |
proc newButtonStyled*(c: PContainer; color: TColor = Green; | |
onClick: proc(b: PButton) = nil): PButton {.discardable.} = | |
result = newButton(c, "##", onClick) | |
result.text.setColor color | |
method hide*(c: PClickable) = c.hidden = true | |
method show*(c: PClickable) = c.hidden = false | |
method isHidden*(c: PClickable): bool= return c.hidden | |
method draw*(window: PRenderWindow; w: PWidget) = nil | |
method draw*(window: PRenderWindow; w: PWidget; dt: float) = nil | |
method update*(w: PWidget; dt: float) = nil | |
method update*(b: PButton; dt: float) = | |
unless b.updateProc.isNil: | |
b.updateProc(b, dt) | |
method update*(t: PTextArea; dt: float) = | |
discard """for i in 0.. <t.height: | |
if t.texts[i].isNil: | |
echo "texts was nil?" | |
else: | |
t.texts[i].set_string t.lines[i]""" | |
method update*(n: PNotifyArea; dt: float) = | |
var i = 0 | |
var pos = n.pos | |
while i < len(n.texts): | |
n.texts[i].life -= dt | |
if n.texts[i].life <= 0.0: | |
n.texts[i].text.destroy() | |
n.texts.delete i | |
else: | |
n.texts[i].text.set_position pos | |
pack_move(pos, n.layout, n.texts[i].text.get_local_bounds.height) | |
inc i | |
method update*(n: PContainer; dt: float) = | |
for w in n.widgets: | |
update(w, dt) | |
method draw*(window: PRenderWindow; n: PNotifyArea) = | |
for t in n.texts: | |
window.draw t.text | |
method draw*(window: PRenderWindow; t: PTextArea) = | |
window.draw t.bg | |
t.cursor_sprite.set_position( | |
(t.cursor * vec2f(t.glyphsize.width, t.glyphsize.height)) + | |
t.text_proto.get_position) | |
window.draw t.cursor_sprite | |
for i in 0..high(t.texts): | |
window.draw t.texts[i] | |
method draw*(window: PrenderWindow; b: PButton) = | |
window.draw b.text | |
method draw*(window: PRenderWindow; h: PHandle) = | |
window.draw h.widget | |
window.draw h.bg | |
window.draw h.text | |
method draw*(window: PRenderWindow; c: PContainer) = | |
if c.hidden: return | |
for w in c.widgets: | |
draw(window, w) | |
proc updateLine*(t: PTextArea){.inline.} = | |
t.texts[t.cursor.y].setString(t.lines[t.cursor.y]) | |
echo repr(t.lines[t.cursor.y]) | |
proc setCursor*(t: PTextArea; x, y: int) = | |
t.cursor.x = x.max(0).min(t.width-1).cint | |
t.cursor.y = y.max(0).min(t.height-1).cint | |
proc moveCursor*(t: PTextArea; x, y: int) = | |
t.updateLine() | |
t.setCursor t.cursor.x+x, t.cursor.y+y | |
if y != 0: t.updateLine() | |
method add*(t: PTextArea, line: string) = | |
t.lines.add line | |
var txt = t.textProto.copy() | |
txt.setstring line | |
t.texts.add txt | |
t.updateline(high(t.texts)) | |
proc add_output*(t: PTextArea; line: string) = | |
t.lines[t.cursor.y] = line | |
t.move_cursor 0, 1 | |
proc addlines*(t: PTextArea; num: int) = | |
for i in 0..num-1: | |
t.add("") | |
proc newTextGrid*(c: PContainer; pos = vec2f(0, 0); width = 80; height = 25): PTextArea = | |
new(result) | |
result.lines = @[] | |
result.texts = @[] | |
result.height = height | |
result.width = width | |
var glyp = guiFont.getGlyph('#'.cuint, 16, false) | |
result.textProto = newText("", guiFont, 16) | |
result.textProto.set_color Green | |
result.textProto.set_position pos + c.get_position() | |
result.glyphsize = glyp.bounds | |
result.glyphsize.height = 16 | |
result.glyphsize.width = 10 | |
result.bg = sfml.newRectangleShape( | |
vec2f(result.glyphsize.width * width, | |
result.glyphsize.height* height)) | |
result.cursor_sprite = new_rectangle_shape(vec2f( | |
result.glyphsize.width.float, result.glyphsize.height.float)) | |
result.cursor_sprite.set_fill_color Transparent | |
result.cursor_sprite.set_outline_color Blue | |
result.cursor_sprite.set_outline_thickness 1.5 | |
addLines(result, height) | |
set_position(result, pos + c.get_position) | |
discard """for i in 0.. <height: | |
var txt = text.copy() | |
txt.setstring s | |
result.texts.add txt | |
result.lines.add s | |
pos.y += result.glyphsize.height.float | |
result.texts.last.setPosition pos""" | |
c.add result | |
method handle*(w: PWidget; e: var TTextEvent) = nil | |
method handle*(t: PTextArea; evt: var TTextEvent) = | |
let c = evt.unicode | |
if c in 31..126: | |
if t.lines.len-1 < t.cursor.y: | |
t.addlines(t.cursor.y - t.lines.len + 1) | |
if high(t.lines[t.cursor.y]) < t.cursor.x: | |
echo "setting len to ", t.cursor.x + 1, " ", (t.cursor.x + 1) - high(t.lines[t.cursor.y]) | |
var h = len(t.lines[t.cursor.y]) | |
t.lines[t.cursor.y].set_len(t.cursor.x + 1) | |
while h < len(t.lines[t.cursor.y]): | |
echo h | |
t.lines[t.cursor.y][h] = ' ' | |
inc h | |
#t.cursor.x = len(t.lines[t.cursor.y]).cint | |
echo("Cursor is ", $t.cursor, " ", char(c)) | |
t.lines[t.cursor.y][t.cursor.x] = char(c) | |
t.moveCursor(1, 0) | |
#echo "recorded" | |
elif c == 8: ### should have named it D | |
let rem = substr(t.lines[t.cursor.y], t.cursor.x+1) | |
t.lines[t.cursor.y].setLen(t.cursor.x) | |
echo(t.lines[t.cursor.y], " + ", rem) | |
t.lines[t.cursor.y].add rem | |
t.moveCursor(-1, 0) | |
elif c == 127: ## delete | |
## str[0..cursor] + str[cursor+1 .. -1] | |
let rem = substr(t.lines[t.cursor.y], t.cursor.x+1) | |
t.lines[t.cursor.y].setLen(t.cursor.x) | |
echo(t.lines[t.cursor.y], " + ", rem) | |
t.lines[t.cursor.y].add rem | |
t.updateline() | |
elif c == 13: ##\n | |
t.moveCursor(0, 1) | |
else: | |
echo c | |
#t.cursor.x = max(0, min(t.width, t.cursor.x + x)).cint | |
#t.cursor.y = max(0, min(t.height, t.cursor.y + y)).cint | |
method handle*(t: PTextArea; evt: var TKeyEvent) = | |
case evt.code | |
of KeyLeft: | |
#t.cursor.x = max(0, t.cursor.x - 1).cint | |
t.movecursor(-1, 0) | |
of KeyRight: | |
#t.cursor.x = max(t.width, t.cursor.x + 1).cint | |
t.movecursor(1, 0) | |
of KeyUp: | |
t.moveCursor(0, -1) | |
of KeyDown: | |
#t.cursor.y = max(t.height, t.cursor.y + 1).cint | |
t.movecursor(0, 1) | |
of KeyHome: | |
t.movecursor(-t.cursor.x, 0) | |
of KeyEnd: | |
t.moveCursor(high(t.lines[t.cursor.y])-t.cursor.x, 0) | |
else: | |
nil | |
method setPosition*(t: PTextArea; val: TVector2f) = | |
t.text_proto.setPosition val | |
for i in 0..high(t.texts): | |
updateline(t, i) | |
t.bg.set_position val | |
t.bounds = t.bg.get_global_bounds | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment