work on textfield; add client.img_blit_to() (still unverified)

This commit is contained in:
triplefox 2012-12-10 18:40:24 -08:00
parent ccbdaca1f8
commit ad7f7fc6c6
4 changed files with 115 additions and 23 deletions

1
lua.c
View File

@ -83,6 +83,7 @@ struct icelua_entry icelua_client[] = {
{icelua_fn_client_model_render_bone_global, "model_render_bone_global"},
{icelua_fn_client_model_render_bone_local, "model_render_bone_local"},
{icelua_fn_client_img_blit, "img_blit"},
{icelua_fn_client_img_blit_to, "img_blit_to"},
{NULL, NULL}
};

View File

@ -151,3 +151,31 @@ int icelua_fn_common_img_get_dims(lua_State *L)
return 2;
}
int icelua_fn_client_img_blit_to(lua_State *L)
{
int top = icelua_assert_stack(L, 4, 9);
int dx, dy, bw, bh, sx, sy;
uint32_t color;
img_t *dest = lua_touserdata(L, 1);
if(dest == NULL || dest->udtype != UD_IMG)
return luaL_error(L, "not an image");
img_t *source = lua_touserdata(L, 2);
if(source == NULL || source->udtype != UD_IMG)
return luaL_error(L, "not an image");
dx = lua_tointeger(L, 3);
dy = lua_tointeger(L, 4);
bw = (top < 5 ? source->head.width : lua_tointeger(L, 5));
bh = (top < 6 ? source->head.height : lua_tointeger(L, 6));
sx = (top < 7 ? 0 : lua_tointeger(L, 7));
sy = (top < 8 ? 0 : lua_tointeger(L, 8));
color = (top < 9 ? 0xFFFFFFFF : (uint32_t)lua_tointeger(L, 9));
render_blit_img(dest->pixels, dest->head.width, dest->head.height,
dest->head.width,
source, dx, dy, bw, bh, sx, sy, color);
return 0;
}

View File

@ -1,12 +1,4 @@
-- look into actual drawing functionality!~
-- the client drawing code requires manual memory management:
-- we have to allocate a buffer and draw pixels to it
-- this code can't deal with that problem...
-- lib_gui will have to provide a layer that takes the abstract APIs here and adds drawing functions
-- on top. the abstract API can assist by adding a "dirty" flag so that cache management is straightforward.
-- sketch listener and collision system:
-- rect and layers detection (derive layers from hierarchy)
-- onDown onUp onMove onClick(down+up inside collision) onDrag(down inside collision, movement) onKeyboard
-- when will mouse cursor be visible? important engine consideration!

View File

@ -190,20 +190,27 @@ function gui_create_fixwidth_font(image, char_width, char_height, indexing_fn)
-- print text with topleft at x, y, color c, string str
function this.print(x, y, c, str, buffer)
buffer = buffer or client
local i
for i=1,#str do
local idx = this.indexing_fn(string.byte(str, i))
buffer.img_blit(this.image, x, y, this.width, this.height, idx*this.width, 0, c)
if buffer == nil then
local temp = common.img_new(this.width, this.height)
client.img_blit_to(temp, this.image, 0, 0, this.width, this.height,
idx*this.width, 0, c)
common.img_pixel_set(temp, 0, 0, 0xFFFF0000)
client.img_blit(temp, x, y)
common.img_free(temp)
--client.img_blit(this.image, x, y, this.width, this.height, idx*this.width, 0, c)
else
client.img_blit_to(buffer, this.image, x, y, this.width, this.height, idx*this.width, 0, c)
end
x = x + this.width
end
local i
end
-- print a selection of precomputed text
function this.print_precomputed(data, offx, offy, buffer)
buffer = buffer or client
for y=1,#data do
for x=1,#data[y] do
local char = data[y][x][1]
@ -211,8 +218,13 @@ function gui_create_fixwidth_font(image, char_width, char_height, indexing_fn)
local px = data[y][x][3] + offx
local py = data[y][x][4] + offy
local c = data[y][x][5]
buffer.img_blit(this.image, px, py, this.width, this.height,
idx*this.width, 0, c)
if buffer == nil then
client.img_blit(this.image, px, py, this.width, this.height,
idx*this.width, 0, c)
else
client.img_blit_to(buffer, this.image, px, py, this.width, this.height,
idx*this.width, 0, c)
end
end
end
@ -354,24 +366,83 @@ function gui_create_scene(width, height)
end
function scene.textfield(options)
-- store a text buffer in here and its last render state in here...
-- define the width and height to be the width and height of the text...
-- additional formatting?
local this = scene.display_object(options)
-- if we specified width and height in options, we are implicitly using wordwrapping?
-- no...
this.wordwrap = options.wordwrap or true
this.color = options.color or 0xFF88FF88
this.autosize = options.autosize or true
this.font = options.font or font_mini
this.use_img = true
-- so, we are computing the text around offset 0, 0
-- but when we go to display or collide with it, we're going to have to
-- apply the widget offsets on top.
-- TODO: cursor + text selection collision, data structure, rendering
-- TODO: compute_unwrapped should allow new lines...
-- TODO: check to see if the draw-to-buffer method I made is actually any good
function this.setter_keys.width(w)
if this.autosize == false then
rawset(this, 'width', w)
end
end
function this.setter_keys.height(h)
if this.autosize == false then
rawset(this, 'height', h)
end
end
function this._recalc_size()
if this.wordwrap == true then
this.text_cache = this.font.compute_wordwrap(this.width,
0, 0, this.color, this._text)
else
this.text_cache = this.font.compute_unwrapped(0, 0,
this.color, this._text)
end
if this.autosize then
local dim = this.font.dimensions(this.text_cache)
rawset(this, 'width', dim.width)
rawset(this, 'height', dim.height)
end
this.dirty = true
end
function this.getter_keys.text()
return this._text
end
function this.setter_keys.text(str)
this._text = str
this._recalc_size()
end
function this.draw_update()
this.font.print_precomputed(this.text_cache, 0, 0, this.img)
common.img_pixel_set(this.img, 0, 0, 0xFFFF0000)
common.img_pixel_set(this.img, 1, 0, 0xFFFF0000)
common.img_pixel_set(this.img, 0, 1, 0xFFFF0000)
common.img_pixel_set(this.img, 1, 1, 0xFFFF0000)
end
this.text = options.text or ""
return this
end
-- TEST CODE
--local frame = scene.rect_frame{width=320,height=320, x=width/2, y=height/2}
--local frame2 = scene.rect_frame{width=32,height=32, x=0, y=0}
--local frame3 = scene.rect_frame{width=32,height=32, x=64, y=96}
local frame = scene.rect_frame{width=320,height=320, x=width/2, y=height/2}
local frame2 = scene.rect_frame{width=32,height=32, x=0, y=0}
local frame3 = scene.rect_frame{width=32,height=32, x=64, y=96}
local text1 = scene.textfield{width=400,height=100, text="hello world"}
--root.add_child(frame)
--frame.add_child(frame2)
--frame.add_child(frame3)
root.add_child(text1)
return scene