mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge branch 'cursor' into djvu-highlight
This commit is contained in:
58
blitbuffer.c
58
blitbuffer.c
@@ -366,6 +366,63 @@ static int paintRect(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int invertRect(lua_State *L) {
|
||||
BlitBuffer *dst = (BlitBuffer*) luaL_checkudata(L, 1, "blitbuffer");
|
||||
int x = luaL_checkint(L, 2);
|
||||
int y = luaL_checkint(L, 3);
|
||||
int w = luaL_checkint(L, 4);
|
||||
int h = luaL_checkint(L, 5);
|
||||
uint8_t *dstptr;
|
||||
|
||||
int cy, cx;
|
||||
if(w <= 0 || h <= 0 || x >= dst->w || y >= dst->h) {
|
||||
return 0;
|
||||
}
|
||||
if(x + w > dst->w) {
|
||||
w = dst->w - x;
|
||||
}
|
||||
if(y + h > dst->h) {
|
||||
h = dst->h - y;
|
||||
}
|
||||
|
||||
if(x & 1) {
|
||||
/* This will invert the leftmost column
|
||||
* in the case when x is odd. After this,
|
||||
* x will become even. */
|
||||
dstptr = (uint8_t*)(dst->data +
|
||||
y * dst->pitch +
|
||||
x / 2);
|
||||
for(cy = 0; cy < h; cy++) {
|
||||
*dstptr ^= 0x0F;
|
||||
dstptr += dst->pitch;
|
||||
}
|
||||
x++;
|
||||
w--;
|
||||
}
|
||||
dstptr = (uint8_t*)(dst->data +
|
||||
y * dst->pitch +
|
||||
x / 2);
|
||||
for(cy = 0; cy < h; cy++) {
|
||||
for(cx = 0; cx < w/2; cx++) {
|
||||
*(dstptr+cx) ^= 0xFF;
|
||||
}
|
||||
dstptr += dst->pitch;
|
||||
}
|
||||
if(w & 1) {
|
||||
/* This will invert the rightmost column
|
||||
* in the case when (w & 1) && !(x & 1) or
|
||||
* !(w & 1) && (x & 1). */
|
||||
dstptr = (uint8_t*)(dst->data +
|
||||
y * dst->pitch +
|
||||
(x + w) / 2);
|
||||
for(cy = 0; cy < h; cy++) {
|
||||
*dstptr ^= 0xF0;
|
||||
dstptr += dst->pitch;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct luaL_reg blitbuffer_func[] = {
|
||||
{"new", newBlitBuffer},
|
||||
{NULL, NULL}
|
||||
@@ -378,6 +435,7 @@ static const struct luaL_reg blitbuffer_meth[] = {
|
||||
{"addblitFrom", addblitToBuffer},
|
||||
{"blitFullFrom", blitFullToBuffer},
|
||||
{"paintRect", paintRect},
|
||||
{"invertRect", invertRect},
|
||||
{"free", freeBlitBuffer},
|
||||
{"__gc", freeBlitBuffer},
|
||||
{NULL, NULL}
|
||||
|
||||
81
graphics.lua
81
graphics.lua
@@ -6,6 +6,7 @@ blitbuffer.paintBorder = function (bb, x, y, w, h, bw, c)
|
||||
bb:paintRect(x+w-bw, y+bw, bw, h - 2*bw, c)
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Draw a progress bar according to following args:
|
||||
|
||||
@@ -27,3 +28,83 @@ blitbuffer.progressBar = function (bb, x, y, w, h,
|
||||
fb.bb:paintRect(x+load_m_w, y+load_m_h,
|
||||
(w-2*load_m_w)*load_percent, (h-2*load_m_h), c)
|
||||
end
|
||||
|
||||
|
||||
|
||||
------------------------------------------------
|
||||
-- Start of Cursor class
|
||||
------------------------------------------------
|
||||
|
||||
Cursor = {
|
||||
x_pos = 0,
|
||||
y_pos = 0,
|
||||
--color = 15,
|
||||
h = 10,
|
||||
w = nil,
|
||||
line_w = nil,
|
||||
}
|
||||
|
||||
function Cursor:new(o)
|
||||
o = o or {}
|
||||
o.x_pos = o.x_pos or self.x_pos
|
||||
o.y_pos = o.y_pos or self.y_pos
|
||||
o.h = o.h or self.h
|
||||
|
||||
o.w = o.h / 3
|
||||
o.line_w = math.floor(o.h / 10)
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Cursor:_draw(x, y)
|
||||
local body_h = self.h - self.line_w
|
||||
-- paint upper horizontal line
|
||||
fb.bb:invertRect(x, y, self.w, self.line_w/2)
|
||||
-- paint middle vertical line
|
||||
fb.bb:invertRect(x+(self.w/2)-(self.line_w/2), y+self.line_w/2,
|
||||
self.line_w, body_h)
|
||||
-- paint lower horizontal line
|
||||
fb.bb:invertRect(x, y+body_h+self.line_w/2, self.w, self.line_w/2)
|
||||
end
|
||||
|
||||
function Cursor:draw()
|
||||
self:_draw(self.x_pos, self.y_pos)
|
||||
end
|
||||
|
||||
function Cursor:clear()
|
||||
self:_draw(self.x_pos, self.y_pos)
|
||||
end
|
||||
|
||||
function Cursor:move(x_off, y_off)
|
||||
self.x_pos = self.x_pos + x_off
|
||||
self.y_pos = self.y_pos + y_off
|
||||
end
|
||||
|
||||
function Cursor:moveHorizontal(x_off)
|
||||
self.x_pos = self.x_pos + x_off
|
||||
end
|
||||
|
||||
function Cursor:moveVertical(x_off)
|
||||
self.y_pos = self.y_pos + y_off
|
||||
end
|
||||
|
||||
function Cursor:moveAndDraw(x_off, y_off)
|
||||
self:clear()
|
||||
self:move(x_off, y_off)
|
||||
self:draw()
|
||||
end
|
||||
|
||||
function Cursor:moveHorizontalAndDraw(x_off)
|
||||
self:clear()
|
||||
self:move(x_off, 0)
|
||||
self:draw()
|
||||
end
|
||||
|
||||
function Cursor:moveVerticalAndDraw(y_off)
|
||||
self:clear()
|
||||
self:move(0, y_off)
|
||||
self:draw()
|
||||
end
|
||||
|
||||
|
||||
146
inputbox.lua
146
inputbox.lua
@@ -4,6 +4,8 @@ require "graphics"
|
||||
|
||||
InputBox = {
|
||||
-- Class vars:
|
||||
h = 100,
|
||||
input_slot_w = nil,
|
||||
input_start_x = 145,
|
||||
input_start_y = nil,
|
||||
input_cur_x = nil, -- points to the start of next input pos
|
||||
@@ -15,44 +17,75 @@ InputBox = {
|
||||
shiftmode = false,
|
||||
altmode = false,
|
||||
|
||||
cursor = nil,
|
||||
|
||||
-- font for displaying input content
|
||||
-- we have to use mono here for better distance controlling
|
||||
face = freetype.newBuiltinFace("mono", 25),
|
||||
fhash = "m25",
|
||||
fheight = 25,
|
||||
fwidth = 16,
|
||||
fwidth = 15,
|
||||
}
|
||||
|
||||
function InputBox:setDefaultInput(text)
|
||||
self.input_string = ""
|
||||
self:addString(text)
|
||||
--self.input_cur_x = self.input_start_x + (string.len(text) * self.fwidth)
|
||||
--self.input_string = text
|
||||
end
|
||||
|
||||
function InputBox:addString(str)
|
||||
for i = 1, #str do
|
||||
self:addChar(str:sub(i,i))
|
||||
end
|
||||
function InputBox:refreshText()
|
||||
-- clear previous painted text
|
||||
fb.bb:paintRect(140, self.input_start_y-19,
|
||||
self.input_slot_w, self.fheight, self.input_bg)
|
||||
-- paint new text
|
||||
renderUtf8Text(fb.bb, self.input_start_x, self.input_start_y,
|
||||
self.face, self.fhash,
|
||||
self.input_string, 0)
|
||||
end
|
||||
|
||||
function InputBox:addChar(char)
|
||||
renderUtf8Text(fb.bb, self.input_cur_x, self.input_start_y, self.face, self.fhash,
|
||||
char, true)
|
||||
fb:refresh(1, self.input_cur_x, self.input_start_y-19, self.fwidth, self.fheight)
|
||||
self.cursor:clear()
|
||||
|
||||
-- draw new text
|
||||
local cur_index = (self.cursor.x_pos + 3 - self.input_start_x)
|
||||
/ self.fwidth
|
||||
self.input_string = self.input_string:sub(0,cur_index)..char..
|
||||
self.input_string:sub(cur_index+1)
|
||||
self:refreshText()
|
||||
self.input_cur_x = self.input_cur_x + self.fwidth
|
||||
self.input_string = self.input_string .. char
|
||||
-- draw new cursor
|
||||
self.cursor:moveHorizontal(self.fwidth)
|
||||
self.cursor:draw()
|
||||
|
||||
fb:refresh(1, self.input_start_x-5, self.input_start_y-25,
|
||||
self.input_slot_w, self.h-25)
|
||||
end
|
||||
|
||||
function InputBox:delChar()
|
||||
if self.input_start_x == self.input_cur_x then
|
||||
return
|
||||
end
|
||||
|
||||
self.cursor:clear()
|
||||
|
||||
-- draw new text
|
||||
local cur_index = (self.cursor.x_pos + 3 - self.input_start_x)
|
||||
/ self.fwidth
|
||||
self.input_string = self.input_string:sub(0,cur_index-1)..
|
||||
self.input_string:sub(cur_index+1, -1)
|
||||
self:refreshText()
|
||||
self.input_cur_x = self.input_cur_x - self.fwidth
|
||||
--fill last character with blank rectangle
|
||||
fb.bb:paintRect(self.input_cur_x, self.input_start_y-19,
|
||||
self.fwidth, self.fheight, self.input_bg)
|
||||
fb:refresh(1, self.input_cur_x, self.input_start_y-19, self.fwidth, self.fheight)
|
||||
self.input_string = self.input_string:sub(0,-2)
|
||||
-- draw new cursor
|
||||
self.cursor:moveHorizontal(-self.fwidth)
|
||||
self.cursor:draw()
|
||||
|
||||
fb:refresh(1, self.input_start_x-5, self.input_start_y-25,
|
||||
self.input_slot_w, self.h-25)
|
||||
end
|
||||
|
||||
function InputBox:clearText()
|
||||
self.cursor:clear()
|
||||
self.input_string = ""
|
||||
self:refreshText()
|
||||
self.cursor.x_pos = self.input_start_x - 3
|
||||
self.cursor:draw()
|
||||
|
||||
fb:refresh(1, self.input_start_x-5, self.input_start_y-25,
|
||||
self.input_slot_w, self.h-25)
|
||||
end
|
||||
|
||||
function InputBox:drawBox(ypos, w, h, title)
|
||||
@@ -66,35 +99,40 @@ function InputBox:drawBox(ypos, w, h, title)
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
|| d_text default to nil (used to set default text in input slot)
|
||||
--]]
|
||||
----------------------------------------------------------------------
|
||||
-- InputBox:input()
|
||||
--
|
||||
-- @title: input prompt for the box
|
||||
-- @d_text: default to nil (used to set default text in input slot)
|
||||
----------------------------------------------------------------------
|
||||
function InputBox:input(ypos, height, title, d_text)
|
||||
local pagedirty = true
|
||||
-- do some initilization
|
||||
self.h = height
|
||||
self.input_start_y = ypos + 35
|
||||
self.input_cur_x = self.input_start_x
|
||||
self.input_slot_w = fb.bb:getWidth() - 170
|
||||
|
||||
if d_text then -- if specified default text, draw it
|
||||
w = fb.bb:getWidth() - 40
|
||||
h = height - 45
|
||||
self:drawBox(ypos, w, h, title)
|
||||
self:setDefaultInput(d_text)
|
||||
fb:refresh(1, 20, ypos, w, h)
|
||||
pagedirty = false
|
||||
else -- otherwise, leave the draw task to the main loop
|
||||
self.input_string = ""
|
||||
self.cursor = Cursor:new {
|
||||
x_pos = self.input_start_x - 3,
|
||||
y_pos = ypos + 13,
|
||||
h = 30,
|
||||
}
|
||||
|
||||
|
||||
-- draw box and content
|
||||
w = fb.bb:getWidth() - 40
|
||||
h = height - 45
|
||||
self:drawBox(ypos, w, h, title)
|
||||
if d_text then
|
||||
self.input_string = d_text
|
||||
self.input_cur_x = self.input_cur_x + (self.fwidth * d_text:len())
|
||||
self.cursor.x_pos = self.cursor.x_pos + (self.fwidth * d_text:len())
|
||||
self:refreshText()
|
||||
end
|
||||
self.cursor:draw()
|
||||
fb:refresh(1, 20, ypos, w, h)
|
||||
|
||||
while true do
|
||||
if pagedirty then
|
||||
w = fb.bb:getWidth() - 40
|
||||
h = height - 45
|
||||
self:drawBox(ypos, w, h, title)
|
||||
fb:refresh(1, 20, ypos, w, h)
|
||||
pagedirty = false
|
||||
end
|
||||
|
||||
local ev = input.waitForEvent()
|
||||
ev.code = adjustKeyEvents(ev)
|
||||
if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then
|
||||
@@ -177,14 +215,30 @@ function InputBox:input(ypos, height, title, d_text)
|
||||
self:addChar(" ")
|
||||
elseif ev.code == KEY_PGFWD then
|
||||
elseif ev.code == KEY_PGBCK then
|
||||
elseif ev.code == KEY_FW_LEFT then
|
||||
if (self.cursor.x_pos + 3) > self.input_start_x then
|
||||
self.cursor:moveHorizontalAndDraw(-self.fwidth)
|
||||
fb:refresh(1, self.input_start_x-5, ypos,
|
||||
self.input_slot_w, h)
|
||||
end
|
||||
elseif ev.code == KEY_FW_RIGHT then
|
||||
if (self.cursor.x_pos + 3) < self.input_cur_x then
|
||||
self.cursor:moveHorizontalAndDraw(self.fwidth)
|
||||
fb:refresh(1,self.input_start_x-5, ypos,
|
||||
self.input_slot_w, h)
|
||||
end
|
||||
elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then
|
||||
if self.input_string == "" then
|
||||
self.input_string = nil
|
||||
end
|
||||
break
|
||||
elseif ev.code == KEY_DEL then
|
||||
self:delChar()
|
||||
elseif ev.code == KEY_BACK then
|
||||
if Keys.shiftmode then
|
||||
self:clearText()
|
||||
else
|
||||
self:delChar()
|
||||
end
|
||||
elseif ev.code == KEY_BACK or ev.code == KEY_HOME then
|
||||
self.input_string = nil
|
||||
break
|
||||
end
|
||||
@@ -195,5 +249,7 @@ function InputBox:input(ypos, height, title, d_text)
|
||||
end -- if
|
||||
end -- while
|
||||
|
||||
return self.input_string
|
||||
local return_str = self.input_string
|
||||
self.input_string = ""
|
||||
return return_str
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user