mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge remote branch 'upstream/master'
This commit is contained in:
14
Makefile
14
Makefile
@@ -16,7 +16,7 @@ TTF_FONTS_DIR=$(MUPDFDIR)/fonts
|
||||
|
||||
# set this to your ARM cross compiler:
|
||||
|
||||
HOST:=arm-kindle-linux-gnueabi
|
||||
HOST:=arm-none-linux-gnueabi
|
||||
CC:=$(HOST)-gcc
|
||||
CXX:=$(HOST)-g++
|
||||
STRIP:=$(HOST)-strip
|
||||
@@ -27,16 +27,14 @@ endif
|
||||
HOSTCC:=gcc
|
||||
HOSTCXX:=g++
|
||||
|
||||
SYSROOT=/usr/local/arm/$(HOST)/$(HOST)/sysroot/
|
||||
CFLAGS:=-O3 --sysroot=$(SYSROOT)
|
||||
CXXFLAGS:=-O3 --sysroot=$(SYSROOT)
|
||||
LDFLAGS:= --sysroot=$(SYSROOT)
|
||||
CFLAGS:=-O3 $(SYSROOT)
|
||||
CXXFLAGS:=-O3 $(SYSROOT)
|
||||
LDFLAGS:= $(SYSROOT)
|
||||
ARM_CFLAGS:=-march=armv6
|
||||
# use this for debugging:
|
||||
#CFLAGS:=-O0 -g
|
||||
|
||||
DYNAMICLIBSTDCPP:=-lstdc++
|
||||
STATICLIBSTDCPP=$(SYSROOT)lib/libstdc++.a
|
||||
ifdef STATICLIBSTDCPP
|
||||
DYNAMICLIBSTDCPP:=
|
||||
endif
|
||||
@@ -126,7 +124,7 @@ djvu.o: %.o: %.c
|
||||
$(CC) -c $(KPDFREADER_CFLAGS) -I$(DJVUDIR)/ $< -o $@
|
||||
|
||||
cre.o: %.o: %.cpp
|
||||
$(CC) -c -I$(CRENGINEDIR)/crengine/include/ -I$(LUADIR)/src $< -o $@
|
||||
$(CC) -c -I$(CRENGINEDIR)/crengine/include/ -I$(LUADIR)/src $< -o $@ -lstdc++
|
||||
|
||||
lfs.o: $(LFSDIR)/src/lfs.c
|
||||
$(CC) -c $(CFLAGS) -I$(LUADIR)/src -I$(LFSDIR)/src $(LFSDIR)/src/lfs.c -o $@
|
||||
@@ -202,7 +200,7 @@ $(LUALIB):
|
||||
ifdef EMULATE_READER
|
||||
make -C $(LUADIR)
|
||||
else
|
||||
make -C $(LUADIR) CC="$(HOSTCC)" HOST_CC="$(HOSTCC) -m32" CROSS="$(HOST)-" TARGET_FLAGS="--sysroot=$(SYSROOT) -DLUAJIT_NO_LOG2 -DLUAJIT_NO_EXP2"
|
||||
make -C $(LUADIR) CC="$(HOSTCC)" HOST_CC="$(HOSTCC) -m32" CROSS="$(HOST)-" TARGET_FLAGS="$(SYSROOT) -DLUAJIT_NO_LOG2 -DLUAJIT_NO_EXP2"
|
||||
endif
|
||||
|
||||
thirdparty: $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) $(DJVULIBS) $(CRENGINELIBS)
|
||||
|
||||
69
cre.cpp
69
cre.cpp
@@ -17,6 +17,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define DEBUG_CRENGINE 0
|
||||
|
||||
extern "C" {
|
||||
#include "blitbuffer.h"
|
||||
@@ -424,6 +425,73 @@ static int registerFont(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ported from Android UI kpvcrlib/crengine/android/jni/docview.cpp
|
||||
|
||||
static int findText(lua_State *L) {
|
||||
CreDocument *doc = (CreDocument*) luaL_checkudata(L, 1, "credocument");
|
||||
const char *l_pattern = luaL_checkstring(L, 2);
|
||||
lString16 pattern = lString16(l_pattern);
|
||||
int origin = luaL_checkint(L, 3);
|
||||
bool reverse = luaL_checkint(L, 4);
|
||||
bool caseInsensitive = luaL_checkint(L, 5);
|
||||
|
||||
if ( pattern.empty() )
|
||||
return 0;
|
||||
|
||||
LVArray<ldomWord> words;
|
||||
lvRect rc;
|
||||
doc->text_view->GetPos( rc );
|
||||
int pageHeight = rc.height();
|
||||
int start = -1;
|
||||
int end = -1;
|
||||
if ( reverse ) {
|
||||
// reverse
|
||||
if ( origin == 0 ) {
|
||||
// from end current page to first page
|
||||
end = rc.bottom;
|
||||
} else if ( origin == -1 ) {
|
||||
// from last page to end of current page
|
||||
start = rc.bottom;
|
||||
} else { // origin == 1
|
||||
// from prev page to first page
|
||||
end = rc.top;
|
||||
}
|
||||
} else {
|
||||
// forward
|
||||
if ( origin == 0 ) {
|
||||
// from current page to last page
|
||||
start = rc.top;
|
||||
} else if ( origin == -1 ) {
|
||||
// from first page to current page
|
||||
end = rc.top;
|
||||
} else { // origin == 1
|
||||
// from next page to last
|
||||
start = rc.bottom;
|
||||
}
|
||||
}
|
||||
CRLog::debug("CRViewDialog::findText: Current page: %d .. %d", rc.top, rc.bottom);
|
||||
CRLog::debug("CRViewDialog::findText: searching for text '%s' from %d to %d origin %d", LCSTR(pattern), start, end, origin );
|
||||
if ( doc->text_view->getDocument()->findText( pattern, caseInsensitive, reverse, start, end, words, 200, pageHeight ) ) {
|
||||
CRLog::debug("CRViewDialog::findText: pattern found");
|
||||
doc->text_view->clearSelection();
|
||||
doc->text_view->selectWords( words );
|
||||
ldomMarkedRangeList * ranges = doc->text_view->getMarkedRanges();
|
||||
if ( ranges ) {
|
||||
if ( ranges->length()>0 ) {
|
||||
int pos = ranges->get(0)->start.y;
|
||||
//doc->text_view->SetPos(pos); // commented out not to mask lua code which does the same
|
||||
CRLog::debug("# SetPos = %d", pos);
|
||||
lua_pushinteger(L, ranges->length()); // results found
|
||||
lua_pushinteger(L, pos);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
CRLog::debug("CRViewDialog::findText: pattern not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg cre_func[] = {
|
||||
{"openDocument", openDocument},
|
||||
{"getFontFaces", getFontFaces},
|
||||
@@ -459,6 +527,7 @@ static const struct luaL_Reg credocument_meth[] = {
|
||||
//{"cursorLeft", cursorLeft},
|
||||
//{"cursorRight", cursorRight},
|
||||
{"drawCurrentPage", drawCurrentPage},
|
||||
{"findText", findText},
|
||||
{"close", closeDocument},
|
||||
{"__gc", closeDocument},
|
||||
{NULL, NULL}
|
||||
|
||||
@@ -592,3 +592,40 @@ function CREReader:adjustCreReaderCommands()
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
--- search
|
||||
----------------------------------------------------
|
||||
function CREReader:searchHighLight(search)
|
||||
Debug("FIXME CreReader::searchHighLight", search)
|
||||
|
||||
if self.last_search == nil or self.last_search.search == nil then
|
||||
self.last_search = {
|
||||
search = "",
|
||||
}
|
||||
end
|
||||
|
||||
local origin = 0 -- 0=current 1=next-last -1=first-current
|
||||
if self.last_search.search == search then
|
||||
origin = 1
|
||||
end
|
||||
|
||||
local found, pos = self.doc:findText(
|
||||
search,
|
||||
origin,
|
||||
0, -- reverse: boolean
|
||||
1 -- caseInsensitive: boolean
|
||||
)
|
||||
|
||||
if found then
|
||||
self.pos = pos -- first metch position
|
||||
self:redrawCurrentPage()
|
||||
showInfoMsgWithDelay( found.." hits '"..search.."' pos "..pos, 2000, 1)
|
||||
else
|
||||
showInfoMsgWithDelay( "'"..search.."' not found in document", 2000, 1)
|
||||
end
|
||||
|
||||
self.last_search.search = search
|
||||
|
||||
end
|
||||
|
||||
@@ -402,9 +402,12 @@ function FileChooser:addAllCommands()
|
||||
function(self)
|
||||
local oldname = self:FullFileName()
|
||||
if oldname then
|
||||
local newname = InputBox:input(0, 0, "New filename:", "including extension", true)
|
||||
local name_we = self.files[self.perpage*(self.page-1)+self.current - #self.dirs]
|
||||
local ext = string.lower(string.match(oldname, ".+%.([^.]+)") or "")
|
||||
name_we = string.sub(name_we,1,-2-string.len(ext))
|
||||
local newname = InputBox:input(0, 0, "New filename:", name_we)
|
||||
if newname then
|
||||
newname = self.path.."/"..newname
|
||||
newname = self.path.."/"..newname..'.'..ext
|
||||
os.rename(oldname, newname)
|
||||
os.rename(DocToHistory(oldname), DocToHistory(newname))
|
||||
self:setPath(self.path)
|
||||
@@ -546,6 +549,14 @@ function FileChooser:addAllCommands()
|
||||
return "break"
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_K, MOD_SHIFT, "K",
|
||||
"run calculator",
|
||||
function(self)
|
||||
local CalcBox = InputBox:new{ calcmode = true }
|
||||
CalcBox:input(0, 0, "Calc ")
|
||||
self.pagedirty = true
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- NuPogodi, 23.05.12: returns full filename or nil (if folder)
|
||||
|
||||
11
helppage.lua
11
helppage.lua
@@ -40,8 +40,8 @@ HelpPage = {
|
||||
|
||||
-- Other Class vars:
|
||||
|
||||
|
||||
function HelpPage:show(ypos, height, commands)
|
||||
-- 02.06.12: added parameter 'title' for the header to make this function usable for various documentation purposes
|
||||
function HelpPage:show(ypos, height, commands, title)
|
||||
self.commands = {}
|
||||
self.items = 0
|
||||
local keys = {}
|
||||
@@ -66,7 +66,8 @@ function HelpPage:show(ypos, height, commands)
|
||||
fface_height = math.ceil(fface_height)
|
||||
fface_ascender = math.ceil(fface_ascender)
|
||||
local spacing = face_height + 5
|
||||
local vert_S = self.title_H + 12
|
||||
-- 02.06.12: minor correction to vertical position of displayed items
|
||||
local vert_S = self.title_H + 3
|
||||
|
||||
local perpage = math.floor( (height - ypos - 1 * (fface_height + 5) - vert_S) / spacing )
|
||||
self.page = 1
|
||||
@@ -75,8 +76,8 @@ function HelpPage:show(ypos, height, commands)
|
||||
while true do
|
||||
if is_pagedirty then
|
||||
fb.bb:paintRect(0, ypos, fb.bb:getWidth(), height, 0)
|
||||
-- draw header
|
||||
DrawTitle("Active Hotkeys",self.margin_H,0,self.title_H,self.bg_color,Font:getFace("tfont", 25))
|
||||
-- 02.06.12: one should use it here
|
||||
DrawTitle(title or "Active Hotkeys",self.margin_H,0,self.title_H,self.bg_color,Font:getFace("tfont", 25))
|
||||
local c
|
||||
local max_x = 0
|
||||
for c = 1, perpage do
|
||||
|
||||
412
inputbox.lua
412
inputbox.lua
@@ -6,7 +6,6 @@ require "graphics"
|
||||
----------------------------------------------------
|
||||
-- General inputbox
|
||||
----------------------------------------------------
|
||||
|
||||
InputBox = {
|
||||
-- Class vars:
|
||||
h = 100,
|
||||
@@ -25,9 +24,7 @@ InputBox = {
|
||||
fheight = 25,
|
||||
fwidth = 15,
|
||||
commands = nil,
|
||||
initialized = false,
|
||||
|
||||
-- NuPogodi, 25.05.12: for full UTF8 support
|
||||
|
||||
vk_bg = 3,
|
||||
charlist = {}, -- table to store input string
|
||||
charpos = 1,
|
||||
@@ -35,12 +32,13 @@ InputBox = {
|
||||
-- values to control layouts: min & max
|
||||
min_layout = 2,
|
||||
max_layout = 9,
|
||||
-- default layout = 2, i.e. shiftmode = symbolmode = utf8mode = false
|
||||
layout = 2,
|
||||
layout = 3,
|
||||
-- now bits to toggle the layout mode
|
||||
shiftmode = true, -- toggle chars <> capitals, lowest bit in (layout-2)
|
||||
symbolmode = false, -- toggle chars <> symbols, middle bit in (layout-2)
|
||||
utf8mode = false, -- toggle english <> national, highest bit in (layout-2)
|
||||
shiftmode = true, -- toggle chars <-> capitals, lowest bit in (layout-2)
|
||||
symbolmode = false, -- toggle chars <-> symbols, middle bit in (layout-2)
|
||||
utf8mode = false, -- toggle english <-> national, highest bit in (layout-2)
|
||||
calcmode = false, -- toggle calculator mode
|
||||
calcfunctions = nil, -- math functions for calculator helppage
|
||||
}
|
||||
|
||||
function InputBox:new(o)
|
||||
@@ -127,8 +125,13 @@ end
|
||||
----------------------------------------------------------------------
|
||||
function InputBox:input(ypos, height, title, d_text, is_hint)
|
||||
-- To avoid confusion with old ypos & height parameters, I'd better define
|
||||
-- my own position, at the bottom screen edge (NuPogodi, 26.05.12)
|
||||
-- my own position, at the bottom screen edge
|
||||
ypos = fb.bb:getHeight() - 165
|
||||
-- some corrections for calculator mode
|
||||
if self.calcmode then
|
||||
self:setCalcMode()
|
||||
end
|
||||
|
||||
-- at first, draw titled box and content
|
||||
local h, w = 55, fb.bb:getWidth() - 2
|
||||
self:drawBox(ypos, w, h, title)
|
||||
@@ -142,21 +145,16 @@ function InputBox:input(ypos, height, title, d_text, is_hint)
|
||||
y_pos = ypos + 13,
|
||||
h = 30,
|
||||
}
|
||||
|
||||
if d_text then
|
||||
if is_hint then
|
||||
-- print hint text
|
||||
-- print hint text
|
||||
fb.bb:paintRect(self.input_start_x-5, self.input_start_y-19, self.input_slot_w, self.fheight, self.input_bg)
|
||||
renderUtf8Text(fb.bb, self.input_start_x+5, self.input_start_y, self.face, d_text, 0)
|
||||
fb.bb:dimRect(self.input_start_x-5, self.input_start_y-19, self.input_slot_w, self.fheight, self.input_bg)
|
||||
else
|
||||
self.input_string = d_text
|
||||
string.gsub( d_text, "(.)", function(char)
|
||||
table.insert(self.charlist, self.charpos, char)
|
||||
self.charpos = self.charpos + 1
|
||||
return ""
|
||||
end)
|
||||
Debug("charlist", self.charlist)
|
||||
|
||||
-- add text to input_string
|
||||
self:StringToCharlist(d_text)
|
||||
self.input_cur_x = self.input_cur_x + (self.fwidth * #self.charlist)
|
||||
self.cursor.x_pos = self.cursor.x_pos + (self.fwidth * #self.charlist)
|
||||
self:refreshText()
|
||||
@@ -164,8 +162,10 @@ function InputBox:input(ypos, height, title, d_text, is_hint)
|
||||
end
|
||||
self.cursor:draw()
|
||||
fb:refresh(1, 1, ypos, w, h)
|
||||
|
||||
local ev, keydef, command, ret_code
|
||||
while true do
|
||||
local ev = input.saveWaitForEvent()
|
||||
ev = input.saveWaitForEvent()
|
||||
ev.code = adjustKeyEvents(ev)
|
||||
if ev.type == EV_KEY and ev.value ~= EVENT_VALUE_KEY_RELEASE then
|
||||
keydef = Keydef:new(ev.code, getKeyModifier())
|
||||
@@ -183,62 +183,63 @@ function InputBox:input(ypos, height, title, d_text, is_hint)
|
||||
end
|
||||
end -- if
|
||||
end -- while
|
||||
local return_str = self.input_string
|
||||
|
||||
local output = self.input_string
|
||||
self.input_string = ""
|
||||
self.charlist = {}
|
||||
self.charpos = 1
|
||||
return return_str
|
||||
return output
|
||||
end
|
||||
|
||||
function InputBox:setLayoutsTable()
|
||||
-- trying to read the layout from the user-defined file "mykeyboard.lua"
|
||||
local ok, stored = pcall(dofile,"./mykeyboard.lua")
|
||||
-- trying to read the layout from the user-defined file
|
||||
local ok, stored = pcall(dofile, lfs.currentdir() .. "/mykeyboard.lua")
|
||||
if ok then
|
||||
self.INPUT_KEYS = stored
|
||||
else -- if an error happens, we use the default layout
|
||||
self.INPUT_KEYS = {
|
||||
{ KEY_Q, "Q", "q", "1", "!", "Я", "я", "1", "!", },
|
||||
{ KEY_W, "W", "w", "2", "?", "Ж", "ж", "2", "?", },
|
||||
{ KEY_E, "E", "e", "3", "#", "Е", "е", "3", "«", },
|
||||
{ KEY_R, "R", "r", "4", "@", "Р", "р", "4", "»", },
|
||||
{ KEY_T, "T", "t", "5", "%", "Т", "т", "5", ":", },
|
||||
{ KEY_E, "E", "e", "3", "|", "Е", "е", "3", "«", },
|
||||
{ KEY_R, "R", "r", "4", "#", "Р", "р", "4", "»", },
|
||||
{ KEY_T, "T", "t", "5", "@", "Т", "т", "5", ":", },
|
||||
{ KEY_Y, "Y", "y", "6", "‰", "Ы", "ы", "6", ";", },
|
||||
{ KEY_U, "U", "u", "7", "\'", "У", "у", "7", "~", },
|
||||
{ KEY_U, "U", "u", "7", "'", "У", "у", "7", "~", },
|
||||
{ KEY_I, "I", "i", "8", "`", "И", "и", "8", "(",},
|
||||
{ KEY_O, "O", "o", "9", ":", "О", "о", "9", ")",},
|
||||
{ KEY_P, "P", "p", "0", ";", "П", "п", "0", "=", },
|
||||
-- middle raw
|
||||
{ KEY_A, "A", "a", "+", "…", "А", "а", "Ш", "ш", },
|
||||
{ KEY_S, "S", "s", "-", "_", "С", "с", "Ѕ", "ѕ", },
|
||||
{ KEY_D, "D", "d", "*", "¦", "Д", "д", "Э", "э", },
|
||||
{ KEY_F, "F", "f", "/", "|", "Ф", "ф", "Ю", "ю", },
|
||||
{ KEY_G, "G", "g", "\\", "„", "Г", "г", "Ґ", "ґ", },
|
||||
{ KEY_H, "H", "h", "=", "“", "Ч", "ч", "Ј", "ј", },
|
||||
{ KEY_D, "D", "d", "*", "=", "Д", "д", "Э", "э", },
|
||||
{ KEY_F, "F", "f", "/", "\\", "Ф", "ф", "Ю", "ю", },
|
||||
{ KEY_G, "G", "g", "%", "„", "Г", "г", "Ґ", "ґ", },
|
||||
{ KEY_H, "H", "h", "^", "“", "Ч", "ч", "Ј", "ј", },
|
||||
{ KEY_J, "J", "j", "<", "”", "Й", "й", "І", "і", },
|
||||
{ KEY_K, "K", "k", "ˆ", "\"", "К", "к", "Ќ", "ќ", },
|
||||
{ KEY_K, "K", "k", "=", "\"", "К", "к", "Ќ", "ќ", },
|
||||
{ KEY_L, "L", "l", ">", "~", "Л", "л", "Љ", "љ", },
|
||||
-- lowest raw
|
||||
{ KEY_Z, "Z", "z", "(", "$", "З", "з", "Щ", "щ", },
|
||||
{ KEY_X, "X", "x", ")", "€", "Х", "х", "№", "@", },
|
||||
{ KEY_C, "C", "c", "{", "¥", "Ц", "ц", "Џ", "џ", },
|
||||
{ KEY_V, "V", "v", "}", "£", "В", "в", "Ў", "ў", },
|
||||
{ KEY_B, "B", "b", "[", "‚", "Б", "б", "Ћ", "ћ", },
|
||||
{ KEY_N, "N", "n", "]", "‘", "Н", "н", "Њ", "њ", },
|
||||
{ KEY_M, "M", "m", "&", "’", "М", "м", "Ї", "ї", },
|
||||
{ KEY_DOT, ".", ",", ".", ",", ".", ",", "Є", "є", },
|
||||
{ KEY_C, "C", "c", "&", "¥", "Ц", "ц", "Џ", "џ", },
|
||||
{ KEY_V, "V", "v", ":", "£", "В", "в", "Ў", "ў", },
|
||||
{ KEY_B, "B", "b", "π", "‚", "Б", "б", "Ћ", "ћ", },
|
||||
{ KEY_N, "N", "n", "е", "‘", "Н", "н", "Њ", "њ", },
|
||||
{ KEY_M, "M", "m", "~", "’", "М", "м", "Ї", "ї", },
|
||||
{ KEY_DOT, ",", ".", ".", ",", ",", ".", "Є", "є", },
|
||||
-- Let us make key 'Space' the same for all layouts
|
||||
{ KEY_SPACE," ", " ", " ", " ", " ", " ", " ", " ", },
|
||||
-- Simultaneous pressing Alt + Q..P should also work properly
|
||||
{ KEY_1, "1", " ", " ", " ", "1", " ", " ", " ", },
|
||||
{ KEY_2, "2", " ", " ", " ", "2", " ", " ", " ", },
|
||||
{ KEY_3, "3", " ", " ", " ", "3", " ", " ", " ", },
|
||||
{ KEY_4, "4", " ", " ", " ", "4", " ", " ", " ", },
|
||||
{ KEY_5, "5", " ", " ", " ", "5", " ", " ", " ", },
|
||||
{ KEY_6, "6", " ", " ", " ", "6", " ", " ", " ", },
|
||||
{ KEY_7, "7", " ", " ", " ", "7", " ", " ", " ", },
|
||||
{ KEY_8, "8", " ", " ", " ", "8", " ", " ", " ", },
|
||||
{ KEY_9, "9", " ", " ", " ", "9", " ", " ", " ", },
|
||||
{ KEY_0, "0", " ", " ", " ", "0", " ", " ", " ", },
|
||||
-- Simultaneous pressing Alt + Q..P should also work properly everywhere
|
||||
{ KEY_1, "1", "1", "1", "1", "1", "1", "1", "1", },
|
||||
{ KEY_2, "2", "2", "2", "2", "2", "2", "2", "2", },
|
||||
{ KEY_3, "3", "3", "3", "3", "3", "3", "3", "3", },
|
||||
{ KEY_4, "4", "4", "4", "4", "4", "4", "4", "4", },
|
||||
{ KEY_5, "5", "5", "5", "5", "5", "5", "5", "5", },
|
||||
{ KEY_6, "6", "6", "6", "6", "6", "6", "6", "6", },
|
||||
{ KEY_7, "7", "7", "7", "7", "7", "7", "7", "7", },
|
||||
{ KEY_8, "8", "8", "8", "8", "8", "8", "8", "8", },
|
||||
{ KEY_9, "9", "9", "9", "9", "9", "9", "9", "9", },
|
||||
{ KEY_0, "0", "0", "0", "0", "0", "0", "0", "0", },
|
||||
-- DXG keys
|
||||
{ KEY_SLASH,"/", "\\", "/", "\\", "/", "\\", "/", "\\", },
|
||||
}
|
||||
@@ -281,13 +282,13 @@ function InputBox:DrawVirtualKeyboard()
|
||||
blitbuffer.paintBorder(fb.bb, lx+9*dx-10, vy-dy-r-8, r, r, t, c, r)
|
||||
renderUtf8Text(fb.bb, lx-5+9*dx, vy-dy-3, smfont, "Del", true)
|
||||
-- Sym
|
||||
blitbuffer.paintBorder(fb.bb, lx+8*dx-10, vy-r-8, r, r, t + (r-t)*number(self.symbolmode), c, r)
|
||||
blitbuffer.paintBorder(fb.bb, lx+8*dx-10, vy-r-8, r, r, t + (r-t)*self:num(self.symbolmode), c, r)
|
||||
renderUtf8Text(fb.bb, lx-5+8*dx, vy-3, smfont, "Sym", true)
|
||||
-- Enter
|
||||
blitbuffer.paintBorder(fb.bb, lx+9*dx-10, vy-r-8, r, r, t, c, r)
|
||||
renderUtf8Text(fb.bb, lx+9*dx, vy-2, vkfont, "«", true)
|
||||
-- Menu
|
||||
blitbuffer.paintBorder(fb.bb, lx+10*dx-8, vy-2*dy-r-8, r+50, r, t+(r-t)*number(self.utf8mode), c, r)
|
||||
blitbuffer.paintBorder(fb.bb, lx+10*dx-8, vy-2*dy-r-8, r+50, r, t+(r-t)*self:num(self.utf8mode), c, r)
|
||||
renderUtf8Text(fb.bb, lx+10*dx+11, vy-2*dy-3, smfont, "Menu", true)
|
||||
-- fiveway
|
||||
local h=dy+2*r-2
|
||||
@@ -296,6 +297,14 @@ function InputBox:DrawVirtualKeyboard()
|
||||
fb:refresh(1, 1, fb.bb:getHeight()-120, fb.bb:getWidth()-2, 120)
|
||||
end
|
||||
|
||||
function InputBox:num(bool)
|
||||
return bool and 1 or 0
|
||||
end
|
||||
|
||||
function InputBox:VKLayout(b1, b2, b3)
|
||||
return 2 + self:num(b1) + 2 * self:num(b2) + 4 * self:num(b3)
|
||||
end
|
||||
|
||||
function InputBox:addCharCommands(layout)
|
||||
-- at first, let's define self.layout and extract separate bits as layout modes
|
||||
if layout then
|
||||
@@ -306,25 +315,48 @@ function InputBox:addCharCommands(layout)
|
||||
-- fill the layout modes
|
||||
layout = (layout - 2) % 4
|
||||
self.shiftmode = (layout == 1 or layout == 3)
|
||||
self.symbolmode = (layout == 2 or layout == 3)
|
||||
self.symbolmode = (layout == 2 or layout == 4)
|
||||
self.utf8mode = (self.layout > 5)
|
||||
else -- or, without input parameter, restore layout from current layout modes
|
||||
self.layout = 2 + number(self.shiftmode) + 2 * number(self.symbolmode) + 4 * number(self.utf8mode)
|
||||
self.layout = self:VKLayout(self.shiftmode, self.symbolmode, self.utf8mode)
|
||||
end
|
||||
-- let's define layout called by Shift+Key (to type capitalized chars being in low-case layout)
|
||||
local shift_layout = self:VKLayout(not self.shiftmode, self.symbolmode, self.utf8mode)
|
||||
-- adding the commands
|
||||
for k,v in ipairs(self.INPUT_KEYS) do
|
||||
-- seems to work without removing old commands,
|
||||
self.commands:del(v[1], nil, "")
|
||||
-- just redefining existing ones
|
||||
self.commands:add(v[1], nil, "", "input "..v[self.layout],
|
||||
-- just redefining existing
|
||||
self.commands:add(v[1], nil, "A..Z", "enter character from virtual keyboard (VK)",
|
||||
function(self)
|
||||
self:addChar(v[self.layout])
|
||||
end
|
||||
)
|
||||
-- and commands for chars pressed with Shift
|
||||
self.commands:add(v[1], MOD_SHIFT, "A..Z", "enter capitalized VK-character",
|
||||
function(self)
|
||||
self:addChar(v[shift_layout])
|
||||
end
|
||||
)
|
||||
end
|
||||
self:DrawVirtualKeyboard()
|
||||
end
|
||||
|
||||
function InputBox:StringToCharlist(text)
|
||||
if text == nill then return end
|
||||
-- clear
|
||||
self.charlist = {}
|
||||
self.charpos = 1
|
||||
local prevcharcode, charcode = 0
|
||||
for uchar in string.gfind(text, "([%z\1-\127\194-\244][\128-\191]*)") do
|
||||
charcode = util.utf8charcode(uchar)
|
||||
if prevcharcode then -- utf8
|
||||
self.charlist[#self.charlist+1] = uchar
|
||||
end
|
||||
prevcharcode = charcode
|
||||
end
|
||||
self.input_string = self:CharlistToString()
|
||||
self.charpos = #self.charlist+1
|
||||
end
|
||||
|
||||
function InputBox:CharlistToString()
|
||||
local s, i = ""
|
||||
for i=1, #self.charlist do
|
||||
@@ -333,22 +365,25 @@ function InputBox:CharlistToString()
|
||||
return s
|
||||
end
|
||||
|
||||
function number(bool)
|
||||
return bool and 1 or 0
|
||||
end
|
||||
|
||||
function InputBox:addAllCommands()
|
||||
-- we only initialize once
|
||||
-- if already initialized, we (re)define only calcmode-dependent commands
|
||||
if self.commands then
|
||||
self:ModeDependentCommands()
|
||||
self:DrawVirtualKeyboard()
|
||||
return
|
||||
end
|
||||
self:setLayoutsTable()
|
||||
self.commands = Commands:new{}
|
||||
-- adding command to enter character commands
|
||||
self:addCharCommands()
|
||||
-- adding character commands
|
||||
self:addCharCommands(self.layout)
|
||||
-- adding the rest commands (independent of the selected layout)
|
||||
self.commands:add(KEY_FW_LEFT, nil, "",
|
||||
self.commands:add(KEY_H, MOD_ALT, "H",
|
||||
"show helppage",
|
||||
function(self)
|
||||
self:showHelpPage(self.commands)
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_FW_LEFT, nil, "joypad left",
|
||||
"move cursor left",
|
||||
function(self)
|
||||
if (self.cursor.x_pos + 3) > self.input_start_x then
|
||||
@@ -358,7 +393,17 @@ function InputBox:addAllCommands()
|
||||
end
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_FW_RIGHT, nil, "",
|
||||
self.commands:add(KEY_FW_LEFT, MOD_SHIFT, "left",
|
||||
"move cursor to the first position",
|
||||
function(self)
|
||||
if (self.cursor.x_pos + 3) > self.input_start_x then
|
||||
self.cursor:moveHorizontalAndDraw(-self.fwidth*(self.charpos-1))
|
||||
self.charpos = 1
|
||||
fb:refresh(1, self.input_start_x-5, self.ypos, self.input_slot_w, self.h)
|
||||
end
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_FW_RIGHT, nil, "joypad right",
|
||||
"move cursor right",
|
||||
function(self)
|
||||
if (self.cursor.x_pos + 3) < self.input_cur_x then
|
||||
@@ -368,75 +413,235 @@ function InputBox:addAllCommands()
|
||||
end
|
||||
end
|
||||
)
|
||||
self.commands:add({KEY_ENTER, KEY_FW_PRESS}, nil, "",
|
||||
"submit input content",
|
||||
self.commands:add(KEY_FW_RIGHT, MOD_SHIFT, "right",
|
||||
"move cursor to the last position",
|
||||
function(self)
|
||||
if self.input_string == "" then
|
||||
self.input_string = nil
|
||||
if (self.cursor.x_pos + 3) < self.input_cur_x then
|
||||
self.cursor:moveHorizontalAndDraw(self.fwidth*(#self.charlist+1-self.charpos))
|
||||
self.charpos = #self.charlist + 1
|
||||
fb:refresh(1, self.input_start_x-5, self.ypos, self.input_slot_w, self.h)
|
||||
end
|
||||
return "break"
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_DEL, nil, "",
|
||||
self.commands:add(KEY_DEL, nil, "Del",
|
||||
"delete one character",
|
||||
function(self)
|
||||
self:delChar()
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_DEL, MOD_SHIFT, "",
|
||||
"empty inputbox",
|
||||
self.commands:add(KEY_DEL, MOD_SHIFT, "Del",
|
||||
"delete all characters (empty inputbox)",
|
||||
function(self)
|
||||
self:clearText()
|
||||
end
|
||||
)
|
||||
self.commands:add({KEY_BACK, KEY_HOME}, nil, "",
|
||||
"cancel inputbox",
|
||||
self.commands:addGroup("up/down", { Keydef:new(KEY_FW_DOWN, nil), Keydef:new(KEY_FW_UP, nil) },
|
||||
"goto previous/next VK-layout",
|
||||
function(self)
|
||||
self.input_string = nil
|
||||
return "break"
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_P, MOD_SHIFT, "P",
|
||||
"make screenshot",
|
||||
function(self)
|
||||
Screen:screenshot()
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_FW_DOWN, nil, "joypad down",
|
||||
"goto next keyboard layout",
|
||||
function(self)
|
||||
if self.layout == self.max_layout then self:addCharCommands(self.min_layout)
|
||||
else self:addCharCommands(self.layout+1) end
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_FW_UP, nil, "joypad up",
|
||||
"goto previous keyboard layout",
|
||||
function(self)
|
||||
if self.layout == self.min_layout then self:addCharCommands(self.max_layout)
|
||||
else self:addCharCommands(self.layout-1) end
|
||||
if keydef.keycode == KEY_FW_DOWN then
|
||||
if self.layout == self.max_layout then self:addCharCommands(self.min_layout)
|
||||
else self:addCharCommands(self.layout+1) end
|
||||
else -- KEY_FW_UP
|
||||
if self.layout == self.min_layout then self:addCharCommands(self.max_layout)
|
||||
else self:addCharCommands(self.layout-1) end
|
||||
end
|
||||
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_AA, nil, "Aa",
|
||||
"toggle layout: chars <> CHARS",
|
||||
"toggle VK-layout: chars <> CHARS",
|
||||
function(self)
|
||||
self.shiftmode = not self.shiftmode
|
||||
self:addCharCommands()
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_SYM, nil, "Sym",
|
||||
"toggle layout: chars <> symbols",
|
||||
"toggle VK-layout: chars <> symbols",
|
||||
function(self)
|
||||
self.symbolmode = not self.symbolmode
|
||||
self:addCharCommands()
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_MENU, nil, "Menu",
|
||||
"toggle layout: english <> national",
|
||||
"toggle VK-layout: english <> national",
|
||||
function(self)
|
||||
self.utf8mode = not self.utf8mode
|
||||
self:addCharCommands()
|
||||
end
|
||||
)
|
||||
-- NuPogodi, 02.06.12: calcmode-dependent commands are collected
|
||||
self:ModeDependentCommands() -- here
|
||||
|
||||
self.commands:add({KEY_BACK, KEY_HOME}, nil, "Back",
|
||||
"back",
|
||||
function(self)
|
||||
self.input_string = nil
|
||||
return "break"
|
||||
end
|
||||
)
|
||||
end
|
||||
-----------------------------------------------------------------
|
||||
-- NuPogodi, 02.06.12: Some Help- & Calculator-related functions
|
||||
-----------------------------------------------------------------
|
||||
function InputBox:defineCalcFunctions() -- for the calculator documentation
|
||||
-- to initialize only once
|
||||
if self.calcfunctions then return end
|
||||
|
||||
self.calcfunctions = Commands:new{}
|
||||
-- remove initially added commands
|
||||
self.calcfunctions:del(KEY_INTO_SCREEN_SAVER, nil, "Slider")
|
||||
self.calcfunctions:del(KEY_OUTOF_SCREEN_SAVER, nil, "Slider")
|
||||
self.calcfunctions:del(KEY_CHARGING, nil, "plugin/out usb")
|
||||
self.calcfunctions:del(KEY_NOT_CHARGING, nil, "plugin/out usb")
|
||||
self.calcfunctions:del(KEY_SPACE, MOD_ALT, "Space")
|
||||
|
||||
local s = " " -- space for function groups
|
||||
local a = 100 -- arithmetic functions
|
||||
self.calcfunctions:add(a-1, nil, s:rep(1), string.upper("Ariphmetic operators"))
|
||||
self.calcfunctions:add(a, nil, "+ -", "addition: 1+2=3; substraction: 3-2=1")
|
||||
self.calcfunctions:add(a+1, nil, "* /", "multiplication: 2*2=4; division: 4/2=2")
|
||||
self.calcfunctions:add(a+3, nil, "%", "modulo (remainder): 5.2%2=1.2, π-π%0.01=3.14")
|
||||
local r = 200 -- relations
|
||||
self.calcfunctions:add(r-1, nil, s:rep(2), string.upper("Relational operators"))
|
||||
self.calcfunctions:add(r, nil, "< >", "less: (2<3)=true; more: (2>3)=false")
|
||||
self.calcfunctions:add(r+1, nil, "<=", "less or equal: (3≤3)=true, (2≤1)=false")
|
||||
self.calcfunctions:add(r+2, nil, ">=", "more or equal: (3≥3)=true, (1≥2)=false")
|
||||
self.calcfunctions:add(r+3, nil, "==", "equal: (3==3)=true, (1==2)=false")
|
||||
self.calcfunctions:add(r+4, nil, "~=", "not equal: (6~=8)=true, (3~=3)=false")
|
||||
local l = 300 -- logical
|
||||
self.calcfunctions:add(l-1, nil, s:rep(3), string.upper("Logical operators"))
|
||||
self.calcfunctions:add(l+0, nil, "and, &", "= logical 'and': (4 and 5)=5, (nil & 5)=nil")
|
||||
self.calcfunctions:add(l+1, nil, "or, |", "= logical 'or': (4 or 5)=4, (false | 5)=5")
|
||||
local c = 400 -- constants
|
||||
self.calcfunctions:add(c-1, nil, s:rep(4), string.upper("Some constants"))
|
||||
self.calcfunctions:add(c, nil, "pi, π", "= 3.14159…; sin(π/2)=1, cos(π/2)=0")
|
||||
self.calcfunctions:add(c+1, nil, "е, exp(1)", "= 2.71828…; log(е)=1")
|
||||
local m = 500 -- mathematical
|
||||
self.calcfunctions:add(m-1, nil, s:rep(5), string.upper("Mathematic functions"))
|
||||
self.calcfunctions:add(m, nil, "abs(x)", "absolute value of x: abs(1)=1, abs(-2)=2")
|
||||
self.calcfunctions:add(m+1, nil, "ceil(x)", "round to integer no less than x: ceil(0.4)=1")
|
||||
self.calcfunctions:add(m+2, nil, "floor(x)", "round to integer no greater than x: floor(0.4)=0")
|
||||
self.calcfunctions:add(m+3, nil, "^, pow(x,y)","= power: 2^10=1024, pow(4,0.5)=2")
|
||||
self.calcfunctions:add(m+4, nil, "exp(x), e^x","= exponent: exp(1)=2.71828…")
|
||||
self.calcfunctions:add(m+5, nil, "log(x)", "the natural logarithm: log(e)=1")
|
||||
self.calcfunctions:add(m+6, nil, "log10(x)", "the base 10 logarithm: log10(10)=1")
|
||||
self.calcfunctions:add(m+7, nil, "max(x,…)", "return maximal value: max(0,-1,2,1)=2")
|
||||
self.calcfunctions:add(m+8, nil, "min(x,…)", "return minimal value: min(0,-1,2,1)=-1")
|
||||
self.calcfunctions:add(m+9, nil, "sqrt(x)", "return square root: sqrt(4)=2")
|
||||
local t = 600 -- trigonometrical
|
||||
self.calcfunctions:add(t, nil, s:rep(6), string.upper("Trigonometric functions"))
|
||||
self.calcfunctions:add(t+1, nil, "deg(x)", "convert radians to degrees: deg(π/2)=90")
|
||||
self.calcfunctions:add(t+2, nil, "rad(x)", "convert degrees to radians: rad(180)=3.14159…")
|
||||
self.calcfunctions:add(t+3, nil, "sin(x)", "sine for x given in radians: sin(π/2)=1")
|
||||
self.calcfunctions:add(t+4, nil, "cos(x)", "cosine for x given in radians: cos(π)=-1")
|
||||
self.calcfunctions:add(t+5, nil, "tan(x)", "tangent for x given in radians: tan(π/4)=1")
|
||||
self.calcfunctions:add(t+6, nil, "asin(x)", "inverse sine (in radians): asin(1)/π=0.5")
|
||||
self.calcfunctions:add(t+7, nil, "acos(x)", "inverse cosine (in radians): acos(0)/π=0.5")
|
||||
self.calcfunctions:add(t+8, nil, "atan(x)", "inverse tangent (in radians): atan(1)/π=0.25")
|
||||
self.calcfunctions:add(t+9, nil, "atan2(x,y)", "inverse tangent of two args: = atan(x/y)")
|
||||
local h = 700 -- hyperbolical
|
||||
self.calcfunctions:add(h, nil, s:rep(7), string.upper("Hyperbolic functions"))
|
||||
self.calcfunctions:add(h+1, nil, "sinh(x)", "hyperbolic sine, (exp(x)-exp(-x))/2")
|
||||
self.calcfunctions:add(h+2, nil, "cosh(x)", "hyperbolic cosine, (exp(x)+exp(-x))/2")
|
||||
self.calcfunctions:add(h+3, nil, "tanh(x)", "hyperbolic tangent, sinh(x)/cosh(x)")
|
||||
-- not yet documented > "fmod", "frexp", "huge", "ldexp", "modf", "randomseed", "random"
|
||||
end
|
||||
|
||||
function InputBox:showHelpPage(list, title)
|
||||
-- make inactive input slot
|
||||
self.cursor:clear() -- hide cursor
|
||||
fb.bb:dimRect(self.input_start_x-5, self.input_start_y-19, self.input_slot_w, self.fheight, self.input_bg)
|
||||
fb:refresh(1, self.input_start_x-5, self.ypos, self.input_slot_w, self.h)
|
||||
-- now start the helppage with own list of commands and own title
|
||||
HelpPage:show(0, fb.bb:getHeight()-165, list, title)
|
||||
-- on the helppage-exit, making inactive helpage
|
||||
fb.bb:dimRect(0, 40, fb.bb:getWidth(), fb.bb:getHeight()-205, self.input_bg)
|
||||
fb:refresh(1, 0, 40, fb.bb:getWidth(), fb.bb:getHeight()-205)
|
||||
-- and active input slot
|
||||
self:refreshText()
|
||||
self.cursor:draw() -- show cursor = ready to input
|
||||
fb:refresh(1, self.input_start_x-5, self.ypos, self.input_slot_w, self.h)
|
||||
end
|
||||
|
||||
function InputBox:setCalcMode()
|
||||
--clear previous input
|
||||
self.input_string = ""
|
||||
self.charlist = {}
|
||||
self.charpos = 1
|
||||
-- set proper layouts
|
||||
self.layout = 4 -- digits
|
||||
self.min_layout = 3
|
||||
self.max_layout = 4
|
||||
end
|
||||
|
||||
function InputBox:PrepareStringToCalc()
|
||||
local s = string.lower(self.input_string)
|
||||
-- continue interpreting the input
|
||||
local mathe = { "abs", "acos", "asin", "atan2", "atan", "ceil", "cosh", "cos",
|
||||
"deg", "exp", "floor", "fmod", "frexp", "huge", "ldexp", "log10", "log",
|
||||
"max", "min", "modf", "pi", "pow", "rad", "randomseed", "random",
|
||||
"sinh", "sin", "sqrt", "tanh", "tan", }
|
||||
-- to avoid any ambiguities (like sin & sinh), one has to replace by capitals
|
||||
for i=1, #mathe do
|
||||
s = string.gsub(s, mathe[i], string.upper("math."..mathe[i]))
|
||||
end
|
||||
-- some acronyms for constants & functions
|
||||
s = string.gsub(s, "π", " math.pi ")
|
||||
s = string.gsub(s, "е", " math.exp(1) ")
|
||||
s = string.gsub(s, "&", " and ")
|
||||
s = string.gsub(s, "|", " or ")
|
||||
-- return the whole string in lowercase and eventually replace double "math."
|
||||
return string.gsub(string.lower(s), "math.math.", "math.")
|
||||
end
|
||||
|
||||
-- define whether we need to calculate the result or to return 'self.input_string'
|
||||
function InputBox:ModeDependentCommands()
|
||||
if self.calcmode then
|
||||
-- define what to do with the input_string
|
||||
self.commands:add({KEY_FW_PRESS, KEY_ENTER}, nil, "joypad center",
|
||||
"calculate the result",
|
||||
function(self)
|
||||
local s = self:PrepareStringToCalc()
|
||||
if pcall(function () f = assert(loadstring("r = tostring("..s..")")) end) then
|
||||
f()
|
||||
self:clearText()
|
||||
self.cursor:clear()
|
||||
for i=1, string.len(r) do
|
||||
table.insert(self.charlist, string.sub(r,i,i))
|
||||
end
|
||||
self.charpos = #self.charlist + 1
|
||||
self.input_string = r
|
||||
self:refreshText()
|
||||
self.cursor:moveHorizontal(#self.charlist*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)
|
||||
else
|
||||
showInfoMsgWithDelay("Wrong Input! ", 2000, 1)
|
||||
end -- if pcall
|
||||
end -- function
|
||||
)
|
||||
-- add the calculator help (short list of available functions)
|
||||
-- or, might be better, to make some help document and open it in reader ??
|
||||
self.commands:add(KEY_M, MOD_ALT, "M",
|
||||
"math functions available in calculator",
|
||||
function(self)
|
||||
self:defineCalcFunctions()
|
||||
self:showHelpPage(self.calcfunctions, "Math Functions for Calculator")
|
||||
end
|
||||
)
|
||||
else -- return input_string & close input box
|
||||
self.commands:add({KEY_FW_PRESS, KEY_ENTER}, nil, "joypad center",
|
||||
"submit input content",
|
||||
function(self)
|
||||
if self.input_string == "" then
|
||||
self.input_string = nil
|
||||
end
|
||||
return "break"
|
||||
end
|
||||
)
|
||||
-- delete calculator-specific help
|
||||
self.commands:del(KEY_M, MOD_ALT, "M")
|
||||
end -- if self.calcmode
|
||||
end
|
||||
|
||||
----------------------------------------------------
|
||||
@@ -445,7 +650,6 @@ end
|
||||
----------------------------------------------------
|
||||
|
||||
NumInputBox = InputBox:new{
|
||||
symbolmode = true,
|
||||
layout = 4,
|
||||
charlist = {}
|
||||
charlist = {},
|
||||
}
|
||||
|
||||
@@ -2563,8 +2563,10 @@ function UniReader:addAllCommands()
|
||||
self.commands:add(KEY_DOT, nil, ".",
|
||||
"search and highlight text",
|
||||
function(unireader)
|
||||
Screen:saveCurrentBB()
|
||||
local search = InputBox:input(G_height - 100, 100,
|
||||
"Search:", self.last_search.search )
|
||||
Screen:restoreFromSavedBB()
|
||||
|
||||
if search ~= nil and string.len( search ) > 0 then
|
||||
unireader:searchHighLight(search)
|
||||
|
||||
Reference in New Issue
Block a user