mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge pull request #1783 from houqp/keyboard
support input for keyboard only devices like kindle k3 and dxg
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -30,6 +30,7 @@ i18n
|
||||
/.project
|
||||
|
||||
koreader-android-arm-linux-androideabi
|
||||
koreader-kindle-legacy-arm-kindle-linux-gnueabi
|
||||
koreader-kindle-arm-linux-gnueabi
|
||||
koreader-kobo-arm-linux-gnueabihf
|
||||
koreader-emulator-i686-w64-mingw32
|
||||
@@ -37,4 +38,3 @@ koreader-emulator-x86_64-linux-gnu
|
||||
koreader-emulator-x86_64-pc-linux-gnu
|
||||
koreader-pocketbook-arm-obreey-linux-gnueabi
|
||||
koreader-ubuntu-touch-arm-linux-gnueabihf
|
||||
|
||||
|
||||
13
Makefile
13
Makefile
@@ -54,10 +54,10 @@ all: $(if $(ANDROID),,$(KOR_BASE)/$(OUTPUT_DIR)/luajit)
|
||||
rm -f $(INSTALL_DIR)/koreader/git-rev; echo $(VERSION) > $(INSTALL_DIR)/koreader/git-rev
|
||||
ifneq ($(or $(EMULATE_READER),$(WIN32)),)
|
||||
cp -f $(KOR_BASE)/ev_replay.py $(INSTALL_DIR)/koreader/
|
||||
# create symlink instead of copying files in development mode
|
||||
@echo "[*] create symlink instead of copying files in development mode"
|
||||
cd $(INSTALL_DIR)/koreader && \
|
||||
ln -sf ../../$(KOR_BASE)/$(OUTPUT_DIR)/* .
|
||||
# install front spec only for the emulator
|
||||
@echo "[*] install front spec only for the emulator"
|
||||
cd $(INSTALL_DIR)/koreader/spec && test -e front || \
|
||||
ln -sf ../../../../spec ./front
|
||||
cd $(INSTALL_DIR)/koreader/spec/front/unit && test -e data || \
|
||||
@@ -73,15 +73,16 @@ ifdef ANDROID
|
||||
ln -sf ../../$(ANDROID_DIR)/*.lua .
|
||||
endif
|
||||
ifdef WIN32
|
||||
# install runtime libraries for win32
|
||||
@echo "[*] Install runtime libraries for win32..."
|
||||
cd $(INSTALL_DIR)/koreader && cp ../../$(WIN32_DIR)/*.dll .
|
||||
endif
|
||||
# install plugins
|
||||
@echo "[*] Install plugins"
|
||||
cp -r plugins/* $(INSTALL_DIR)/koreader/plugins/
|
||||
@echo "[*] Installresources"
|
||||
cp -rpL resources/fonts/* $(INSTALL_DIR)/koreader/fonts/
|
||||
install -d $(INSTALL_DIR)/koreader/{screenshots,data/{dict,tessdata},fonts/host,ota}
|
||||
ifeq ($(or $(EMULATE_READER),$(WIN32)),)
|
||||
# clean up, remove unused files for releases
|
||||
@echo "[*] Clean up, remove unused files for releases"
|
||||
rm -rf $(INSTALL_DIR)/koreader/data/{cr3.ini,cr3skin-format.txt,desktop,devices,manual}
|
||||
rm -rf $(INSTALL_DIR)/koreader/fonts/droid/DroidSansFallbackFull.ttf
|
||||
endif
|
||||
@@ -286,6 +287,8 @@ androidupdate: all
|
||||
update:
|
||||
ifeq ($(TARGET), kindle)
|
||||
make kindleupdate
|
||||
else ifeq ($(TARGET), kindle-legacy)
|
||||
make kindleupdate
|
||||
else ifeq ($(TARGET), kobo)
|
||||
make koboupdate
|
||||
else ifeq ($(TARGET), pocketbook)
|
||||
|
||||
42
README.md
42
README.md
@@ -112,44 +112,35 @@ Getting the source
|
||||
|
||||
```
|
||||
git clone https://github.com/koreader/koreader.git
|
||||
cd koreader && make fetchthirdparty
|
||||
cd koreader && ./kodev fetch-thirdparty
|
||||
```
|
||||
|
||||
Building, Running and Testing
|
||||
=============================
|
||||
|
||||
For EReader devices (kindle, kobo, pocketbook)
|
||||
For EReader devices (kindle, kobo, pocketbook, ubuntu-touch)
|
||||
---------------------
|
||||
|
||||
To build installable package for Kindle:
|
||||
```
|
||||
make TARGET=kindle clean update
|
||||
./kodev release kindle
|
||||
```
|
||||
|
||||
To build installable package for Kobo:
|
||||
```
|
||||
make TARGET=kobo clean update
|
||||
./kodev release kobo
|
||||
```
|
||||
|
||||
To build installable package for PocketBook you need first to obtain the SDK
|
||||
from PocketBook:
|
||||
To build installable package for PocketBook:
|
||||
```
|
||||
make pocketbook-toolchain
|
||||
```
|
||||
then similarly with Kindle and Kobo building run this command:
|
||||
```
|
||||
make TARGET=pocketbook clean update
|
||||
./kodev release pocketbook
|
||||
```
|
||||
|
||||
To build installable package for Ubuntu Touch
|
||||
```
|
||||
make TARGET=ubuntu-touch clean update
|
||||
./kodev release ubuntu-touch
|
||||
```
|
||||
|
||||
To run, you must call the script `reader.lua`. Run it without arguments to see
|
||||
usage notes. Note that the script and the `luajit` binary must be in the same
|
||||
directory.
|
||||
|
||||
You may checkout our [nightlybuild script][nb-script] to see how to build a
|
||||
package from scratch.
|
||||
|
||||
@@ -159,15 +150,9 @@ For Android devices
|
||||
Make sure the "android" and "ndk-build" tools are in your PATH variable
|
||||
and the NDK variable points to the root directory of the Android NDK.
|
||||
|
||||
First, run this command to make a standalone android cross compiling toolchain
|
||||
from NDK:
|
||||
Then, run this command to build installable package for Android:
|
||||
```
|
||||
make android-toolchain
|
||||
```
|
||||
|
||||
Then, build installable package for Android:
|
||||
```
|
||||
make TARGET=android clean androidupdate
|
||||
./kodev release android
|
||||
```
|
||||
|
||||
For emulating KOReader on Linux and Windows
|
||||
@@ -175,21 +160,20 @@ For emulating KOReader on Linux and Windows
|
||||
|
||||
To build an emulator on current Linux machine just run:
|
||||
```
|
||||
make clean && make
|
||||
./kodev build
|
||||
```
|
||||
|
||||
If you want to compile the emulator for Windows you need to run:
|
||||
```
|
||||
make TARGET=win32 clean && make TARGET=win32
|
||||
./kodev build win32
|
||||
```
|
||||
|
||||
To run Koreader on your developing machine
|
||||
(you may need to change $(MACHINE) to the arch of your machine such as 'x86_64'):
|
||||
```
|
||||
cd koreader-emulator-$(MACHINE)/koreader && ./reader.lua -d ../../test
|
||||
./kodev run ./test
|
||||
```
|
||||
|
||||
To run unit tests in KOReader:
|
||||
To run unit tests:
|
||||
```
|
||||
make test
|
||||
```
|
||||
|
||||
2
base
2
base
Submodule base updated: e7c0c2fee9...8b751543a9
@@ -249,7 +249,7 @@ function ReaderFooter:getDataFromStatistics(title, pages)
|
||||
local statistics_data = self.ui.doc_settings:readSetting("stats")
|
||||
local sec = 'na'
|
||||
if statistics_data and statistics_data.performance_in_pages then
|
||||
local read_pages = util.tablelength(statistics_data.performance_in_pages)
|
||||
local read_pages = util.tableSize(statistics_data.performance_in_pages)
|
||||
local average_time_per_page = statistics_data.total_time_in_sec / read_pages
|
||||
sec = util.secondsToClock(pages * average_time_per_page, true)
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local isAndroid, android = pcall(require, "android")
|
||||
local isAndroid, _ = pcall(require, "android")
|
||||
local util = require("ffi/util")
|
||||
|
||||
local function probeDevice()
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
local Event = require("ui/event")
|
||||
local TimeVal = require("ui/timeval")
|
||||
local input = require("ffi/input")
|
||||
local util = require("ffi/util")
|
||||
local Math = require("optmath")
|
||||
local DEBUG = require("dbg")
|
||||
local ffi = require("ffi")
|
||||
local _ = require("gettext")
|
||||
local Key = require("device/key")
|
||||
local GestureDetector = require("device/gesturedetector")
|
||||
|
||||
@@ -108,6 +108,7 @@ function KindleDXG:init()
|
||||
device = self,
|
||||
event_map = require("device/kindle/event_map_keyboard"),
|
||||
}
|
||||
self.keyboard_layout = require("device/kindle/keyboard_layout")
|
||||
self.input.open("/dev/input/event0")
|
||||
self.input.open("/dev/input/event1")
|
||||
Kindle.init(self)
|
||||
@@ -124,6 +125,7 @@ function Kindle3:init()
|
||||
device = self,
|
||||
event_map = require("device/kindle/event_map_keyboard"),
|
||||
}
|
||||
self.keyboard_layout = require("device/kindle/keyboard_layout")
|
||||
self.input.open("/dev/input/event0")
|
||||
self.input.open("/dev/input/event1")
|
||||
Kindle.init(self)
|
||||
|
||||
14
frontend/device/kindle/keyboard_layout.lua
Normal file
14
frontend/device/kindle/keyboard_layout.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
return {
|
||||
[1] = {
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I", "Q", "P",
|
||||
},
|
||||
[2] = {
|
||||
"A", "S", "D", "F", "G", "H", "J", "K", "L", "Del",
|
||||
},
|
||||
[3] = {
|
||||
"Z", "X", "C", "V", "B", "N", "M", ".", "Sym", "Enter",
|
||||
},
|
||||
[4] = {
|
||||
"Sym", "Alt", "space", "Aa", "Home", "Back",
|
||||
},
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
local Generic = require("device/generic/device")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
local Geom = require("ui/geometry")
|
||||
local DEBUG = require("dbg")
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@ local Device = Generic:new{
|
||||
needsScreenRefreshAfterResume = no,
|
||||
}
|
||||
|
||||
if os.getenv("DISABLE_TOUCH") == "1" then
|
||||
Device.isTouchDevice = no
|
||||
end
|
||||
|
||||
function Device:init()
|
||||
-- allows to set a viewport via environment variable
|
||||
-- syntax is Lua table syntax, e.g. EMULATE_READER_VIEWPORT="{x=10,w=550,y=5,h=790}"
|
||||
@@ -42,6 +46,8 @@ function Device:init()
|
||||
}
|
||||
end
|
||||
|
||||
self.keyboard_layout = require("device/sdl/keyboard_layout")
|
||||
|
||||
if portrait then
|
||||
self.input:registerEventAdjustHook(self.input.adjustTouchSwitchXY)
|
||||
self.input:registerEventAdjustHook(
|
||||
|
||||
14
frontend/device/sdl/keyboard_layout.lua
Normal file
14
frontend/device/sdl/keyboard_layout.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
return {
|
||||
[1] = {
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
|
||||
},
|
||||
[2] = {
|
||||
"A", "S", "D", "F", "G", "H", "J", "K", "L", "Del",
|
||||
},
|
||||
[3] = {
|
||||
"Z", "X", "C", "V", "B", "N", "M", ".", "Sym", "Enter",
|
||||
},
|
||||
[4] = {
|
||||
"Sym", "Alt", "space", "Aa", "Home", "Back",
|
||||
},
|
||||
}
|
||||
@@ -85,7 +85,7 @@ end
|
||||
-- modal widget should be always on the top
|
||||
-- for refreshtype & refreshregion see description of setDirty()
|
||||
function UIManager:show(widget, refreshtype, refreshregion, x, y)
|
||||
DEBUG("show widget", widget.id)
|
||||
DEBUG("show widget", widget._name)
|
||||
self._running = true
|
||||
local window = {x = x or 0, y = y or 0, widget = widget}
|
||||
-- put this window on top of the toppest non-modal window
|
||||
|
||||
@@ -3,7 +3,6 @@ local UIManager = require("ui/uimanager")
|
||||
local Screen = require("device").screen
|
||||
local Geom = require("ui/geometry")
|
||||
local Event = require("ui/event")
|
||||
local DEBUG = require("dbg")
|
||||
local _ = require("gettext")
|
||||
|
||||
--[[
|
||||
@@ -51,19 +50,21 @@ function InputContainer:_init()
|
||||
end
|
||||
|
||||
function InputContainer:paintTo(bb, x, y)
|
||||
if self[1] == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if not self.dimen then
|
||||
local content_size = self[1]:getSize()
|
||||
self.dimen = Geom:new{w = content_size.w, h = content_size.h}
|
||||
end
|
||||
self.dimen.x = x
|
||||
self.dimen.y = y
|
||||
if self[1] then
|
||||
if self.vertical_align == "center" then
|
||||
local content_size = self[1]:getSize()
|
||||
self[1]:paintTo(bb, x, y + math.floor((self.dimen.h - content_size.h)/2))
|
||||
else
|
||||
self[1]:paintTo(bb, x, y)
|
||||
end
|
||||
if self.vertical_align == "center" then
|
||||
local content_size = self[1]:getSize()
|
||||
self[1]:paintTo(bb, x, y + math.floor((self.dimen.h - content_size.h)/2))
|
||||
else
|
||||
self[1]:paintTo(bb, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -87,7 +88,6 @@ end
|
||||
function InputContainer:onGesture(ev)
|
||||
for name, gsseq in pairs(self.ges_events) do
|
||||
for _, gs_range in ipairs(gsseq) do
|
||||
--DEBUG("gs_range", gs_range)
|
||||
if gs_range:match(ev) then
|
||||
local eventname = gsseq.event or name
|
||||
return self:handleEvent(Event:new(eventname, gsseq.args, ev))
|
||||
@@ -97,6 +97,10 @@ function InputContainer:onGesture(ev)
|
||||
end
|
||||
|
||||
function InputContainer:onInput(input)
|
||||
if self.enter_callback == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
self.input_dialog = InputDialog:new{
|
||||
title = input.title or "",
|
||||
|
||||
8
frontend/ui/widget/container/topcontainer.lua
Normal file
8
frontend/ui/widget/container/topcontainer.lua
Normal file
@@ -0,0 +1,8 @@
|
||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||
|
||||
--[[
|
||||
TopContainer contains its content (1 widget) at the top of its own dimensions
|
||||
--]]
|
||||
local TopContainer = WidgetContainer:new()
|
||||
|
||||
return TopContainer
|
||||
@@ -54,7 +54,7 @@ function InputDialog:init()
|
||||
width = self.width,
|
||||
}
|
||||
}
|
||||
self.input = InputText:new{
|
||||
self.input_widget = InputText:new{
|
||||
text = self.input,
|
||||
hint = self.input_hint,
|
||||
face = self.input_face,
|
||||
@@ -95,9 +95,9 @@ function InputDialog:init()
|
||||
CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
w = self.title_bar:getSize().w,
|
||||
h = self.input:getSize().h,
|
||||
h = self.input_widget:getSize().h,
|
||||
},
|
||||
self.input,
|
||||
self.input_widget,
|
||||
},
|
||||
-- buttons
|
||||
CenterContainer:new{
|
||||
@@ -113,7 +113,7 @@ function InputDialog:init()
|
||||
self[1] = CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
w = Screen:getWidth(),
|
||||
h = Screen:getHeight() - self.input:getKeyboardDimen().h,
|
||||
h = Screen:getHeight() - self.input_widget:getKeyboardDimen().h,
|
||||
},
|
||||
self.dialog_frame,
|
||||
}
|
||||
@@ -132,15 +132,15 @@ function InputDialog:onCloseWidget()
|
||||
end
|
||||
|
||||
function InputDialog:onShowKeyboard()
|
||||
self.input:onShowKeyboard()
|
||||
self.input_widget:onShowKeyboard()
|
||||
end
|
||||
|
||||
function InputDialog:getInputText()
|
||||
return self.input:getText()
|
||||
return self.input_widget:getText()
|
||||
end
|
||||
|
||||
function InputDialog:onClose()
|
||||
self.input:onCloseKeyboard()
|
||||
self.input_widget:onCloseKeyboard()
|
||||
end
|
||||
|
||||
return InputDialog
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local FrameContainer = require("ui/widget/container/framecontainer")
|
||||
local ScrollTextWidget = require("ui/widget/scrolltextwidget")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local FrameContainer = require("ui/widget/container/framecontainer")
|
||||
local VirtualKeyboard = require("ui/widget/virtualkeyboard")
|
||||
local GestureRange = require("ui/gesturerange")
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Device = require("device")
|
||||
local Screen = require("device").screen
|
||||
local Screen = Device.screen
|
||||
local Font = require("ui/font")
|
||||
local util = require("ffi/util")
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local Keyboard
|
||||
|
||||
local InputText = InputContainer:new{
|
||||
text = "",
|
||||
@@ -32,10 +32,10 @@ local InputText = InputContainer:new{
|
||||
focused = true,
|
||||
}
|
||||
|
||||
function InputText:init()
|
||||
self:initTextBox(self.text)
|
||||
self:initKeyboard()
|
||||
if Device:isTouchDevice() then
|
||||
-- only use PhysicalKeyboard if the device does not have touch screen
|
||||
if Device.isTouchDevice() then
|
||||
Keyboard = require("ui/widget/virtualkeyboard")
|
||||
function InputText:initEventListener()
|
||||
self.ges_events = {
|
||||
TapTextBox = {
|
||||
GestureRange:new{
|
||||
@@ -45,6 +45,21 @@ function InputText:init()
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function InputText:onTapTextBox()
|
||||
if self.parent.onSwitchFocus then
|
||||
self.parent:onSwitchFocus(self)
|
||||
end
|
||||
end
|
||||
else
|
||||
Keyboard = require("ui/widget/physicalkeyboard")
|
||||
function InputText:initEventListener() end
|
||||
end
|
||||
|
||||
function InputText:init()
|
||||
self:initTextBox(self.text)
|
||||
self:initKeyboard()
|
||||
self:initEventListener()
|
||||
end
|
||||
|
||||
function InputText:initTextBox(text)
|
||||
@@ -112,20 +127,13 @@ function InputText:initKeyboard()
|
||||
if self.input_type == "number" then
|
||||
keyboard_layout = 3
|
||||
end
|
||||
self.keyboard = VirtualKeyboard:new{
|
||||
self.keyboard = Keyboard:new{
|
||||
layout = keyboard_layout,
|
||||
inputbox = self,
|
||||
width = Screen:getWidth(),
|
||||
height = math.max(Screen:getWidth(), Screen:getHeight())*0.33,
|
||||
}
|
||||
end
|
||||
|
||||
function InputText:onTapTextBox()
|
||||
if self.parent.onSwitchFocus then
|
||||
self.parent:onSwitchFocus(self)
|
||||
end
|
||||
end
|
||||
|
||||
function InputText:unfocus()
|
||||
self.focused = false
|
||||
self[1].color = Blitbuffer.gray(0.5)
|
||||
|
||||
172
frontend/ui/widget/physicalkeyboard.lua
Normal file
172
frontend/ui/widget/physicalkeyboard.lua
Normal file
@@ -0,0 +1,172 @@
|
||||
local CenterContainer = require("ui/widget/container/centercontainer")
|
||||
local BottomContainer = require("ui/widget/container/bottomcontainer")
|
||||
local TopContainer = require("ui/widget/container/topcontainer")
|
||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local FrameContainer = require("ui/widget/container/framecontainer")
|
||||
local HorizontalGroup = require("ui/widget/horizontalgroup")
|
||||
local HorizontalSpan = require("ui/widget/horizontalspan")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local TextWidget = require("ui/widget/textwidget")
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local Device = require("device")
|
||||
local Font = require("ui/font")
|
||||
local Screen = Device.screen
|
||||
local Geom = require("ui/geometry")
|
||||
local util = require("util")
|
||||
local DEBUG = require("dbg")
|
||||
|
||||
|
||||
local PhysicalNumericKey = WidgetContainer:new{
|
||||
key = nil,
|
||||
label = nil,
|
||||
physical_key_label = nil,
|
||||
|
||||
keyboard = nil,
|
||||
callback = nil,
|
||||
mapping = nil,
|
||||
|
||||
width = nil,
|
||||
height = nil,
|
||||
bordersize = 2,
|
||||
face = Font:getFace("infont", 22),
|
||||
pkey_face = Font:getFace("infont", 14),
|
||||
}
|
||||
|
||||
function PhysicalNumericKey:init()
|
||||
local label_widget = TextWidget:new{
|
||||
text = self.label,
|
||||
face = self.face,
|
||||
}
|
||||
self[1] = FrameContainer:new{
|
||||
margin = 0,
|
||||
bordersize = self.bordersize,
|
||||
background = Blitbuffer.COLOR_WHITE,
|
||||
radius = 5,
|
||||
padding = 0,
|
||||
CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
w = self.width - 2*self.bordersize,
|
||||
h = self.height - 2*self.bordersize,
|
||||
},
|
||||
VerticalGroup:new{
|
||||
label_widget,
|
||||
TextWidget:new{
|
||||
fgcolor = Blitbuffer.COLOR_GREY,
|
||||
text = self.physical_key_label,
|
||||
face = self.pkey_face,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
self.dimen = Geom:new{
|
||||
w = self.width,
|
||||
h = self.height,
|
||||
}
|
||||
end
|
||||
|
||||
-- start of PhysicalKeyboard
|
||||
|
||||
local PhysicalKeyboard = InputContainer:new{
|
||||
is_always_active = true,
|
||||
inputbox = nil, -- expect ui/widget/inputtext instance
|
||||
bordersize = 2,
|
||||
padding = 2,
|
||||
height = math.max(Screen:getWidth(), Screen:getHeight())*0.33,
|
||||
key_padding = Screen:scaleBySize(6),
|
||||
}
|
||||
|
||||
function PhysicalKeyboard:init()
|
||||
local all_keys = {}
|
||||
for _,row in ipairs(Device.keyboard_layout) do
|
||||
util.arrayAppend(all_keys, row)
|
||||
end
|
||||
self.key_events = {
|
||||
KeyPress = { { all_keys }, }
|
||||
}
|
||||
|
||||
self.dimen = Geom:new{ w = 0, h = 0 }
|
||||
|
||||
self:setType(self.inputbox.input_type)
|
||||
end
|
||||
|
||||
function PhysicalKeyboard:setType(t)
|
||||
if t == "number" then
|
||||
self.mapping = {
|
||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
|
||||
}
|
||||
self.key_transformer = {}
|
||||
for i,row in ipairs(self.mapping) do
|
||||
for j,key in ipairs(row) do
|
||||
local pkey = Device.keyboard_layout[i][j]
|
||||
self.key_transformer[pkey] = self.mapping[i][j]
|
||||
end
|
||||
end
|
||||
self:setupNumericMappingUI()
|
||||
else
|
||||
-- default mapping
|
||||
self.mapping = Device.keyboard_layout
|
||||
end
|
||||
end
|
||||
|
||||
function PhysicalKeyboard:onKeyPress(ev)
|
||||
local key = ev.key
|
||||
if key == "Back" then
|
||||
DEBUG("TODO: exit keyboard")
|
||||
elseif key == "Del" then
|
||||
self.inputbox:delChar()
|
||||
else
|
||||
if self.key_transformer then
|
||||
key = self.key_transformer[key]
|
||||
end
|
||||
self.inputbox:addChar(key)
|
||||
end
|
||||
end
|
||||
|
||||
function PhysicalKeyboard:setupNumericMappingUI()
|
||||
local key_rows = VerticalGroup:new{}
|
||||
local key_margin = 1
|
||||
local row_len = #self.mapping[1]
|
||||
local base_key_width = math.floor((self.width - row_len*(self.key_padding+2*key_margin) - 2*self.padding)/10)
|
||||
local base_key_height = math.floor((self.height - self.key_padding - 2*self.padding)/4)
|
||||
local key_width = math.floor(base_key_width + self.key_padding)
|
||||
|
||||
for i, kb_row in ipairs(self.mapping) do
|
||||
local row = HorizontalGroup:new{}
|
||||
for j, key in ipairs(kb_row) do
|
||||
if j > 1 then
|
||||
table.insert(row, HorizontalSpan:new{width=key_margin*2})
|
||||
end
|
||||
table.insert(row, PhysicalNumericKey:new{
|
||||
label = key,
|
||||
physical_key_label = Device.keyboard_layout[i][j],
|
||||
width = key_width,
|
||||
height = base_key_height,
|
||||
})
|
||||
end
|
||||
table.insert(key_rows, row)
|
||||
end
|
||||
|
||||
local keyboard_frame = FrameContainer:new{
|
||||
margin = 0,
|
||||
bordersize = 0,
|
||||
radius = 0,
|
||||
padding = self.padding,
|
||||
TopContainer:new{
|
||||
dimen = Geom:new{
|
||||
w = self.width - 2*self.bordersize -2*self.padding,
|
||||
h = self.height - 2*self.bordersize -2*self.padding,
|
||||
},
|
||||
key_rows,
|
||||
}
|
||||
}
|
||||
|
||||
self[1] = BottomContainer:new{
|
||||
dimen = Screen:getSize(),
|
||||
keyboard_frame,
|
||||
}
|
||||
|
||||
self.dimen = keyboard_frame:getSize()
|
||||
end
|
||||
|
||||
return PhysicalKeyboard
|
||||
@@ -10,8 +10,8 @@ local ImageWidget = require("ui/widget/imagewidget")
|
||||
local TextWidget = require("ui/widget/textwidget")
|
||||
local Font = require("ui/font")
|
||||
local Geom = require("ui/geometry")
|
||||
local Screen = require("device").screen
|
||||
local Device = require("device")
|
||||
local Screen = Device.screen
|
||||
local GestureRange = require("ui/gesturerange")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local DEBUG = require("dbg")
|
||||
@@ -26,7 +26,7 @@ local VirtualKey = InputContainer:new{
|
||||
callback = nil,
|
||||
|
||||
width = nil,
|
||||
height = nil,
|
||||
height = math.max(Screen:getWidth(), Screen:getHeight())*0.33,
|
||||
bordersize = 2,
|
||||
face = Font:getFace("infont", 22),
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ function util.gsplit(str, pattern, capture)
|
||||
end)
|
||||
end
|
||||
|
||||
--https://gist.github.com/jesseadams/791673
|
||||
-- https://gist.github.com/jesseadams/791673
|
||||
function util.secondsToClock(seconds, withoutSeconds)
|
||||
seconds = tonumber(seconds)
|
||||
if seconds == 0 or seconds ~= seconds then
|
||||
@@ -66,10 +66,18 @@ function util.secondsToClock(seconds, withoutSeconds)
|
||||
end
|
||||
end
|
||||
|
||||
function util.tablelength(T)
|
||||
-- returns number of keys in a table
|
||||
function util.tableSize(T)
|
||||
local count = 0
|
||||
for _ in pairs(T) do count = count + 1 end
|
||||
return count
|
||||
end
|
||||
|
||||
-- append all elements from t2 into t1
|
||||
function util.arrayAppend(t1, t2)
|
||||
for _,v in ipairs(t2) do
|
||||
table.insert(t1, v)
|
||||
end
|
||||
end
|
||||
|
||||
return util
|
||||
|
||||
272
kodev
Executable file
272
kodev
Executable file
@@ -0,0 +1,272 @@
|
||||
#!/bin/bash
|
||||
|
||||
CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
function setup_env {
|
||||
files=("./koreader-emulator-*/koreader")
|
||||
export EMU_DIR=${files[0]}
|
||||
}
|
||||
|
||||
function kodev-fetch-thirdparty {
|
||||
make fetchthirdparty
|
||||
}
|
||||
|
||||
SUPPORTED_TARGETS="
|
||||
kindle For kindle with touch support
|
||||
kindle-legacy For kindle2/3/4/DXG
|
||||
kobo
|
||||
android
|
||||
pocketbook
|
||||
ubuntu-touch
|
||||
emu (*default) If no TARGET is given, assume emulator
|
||||
win32
|
||||
"
|
||||
|
||||
function kodev-build {
|
||||
BUILD_HELP_MSG="
|
||||
usage: build <TARGET>
|
||||
|
||||
TARGET:
|
||||
${SUPPORTED_TARGETS}"
|
||||
|
||||
case $1 in
|
||||
-h | --help)
|
||||
echo "${BUILD_HELP_MSG}"
|
||||
exit 0
|
||||
;;
|
||||
kindle)
|
||||
make TARGET=kindle
|
||||
;;
|
||||
kobo)
|
||||
make TARGET=kobo
|
||||
;;
|
||||
kindle-legacy)
|
||||
make TARGET=kindle-legacy
|
||||
;;
|
||||
android)
|
||||
if [ ! -d ${CURDIR}/base/toolchain/android-toolchain ]; then
|
||||
make android-toolchain
|
||||
fi
|
||||
make TARGET=android
|
||||
;;
|
||||
pocketbook)
|
||||
if [ ! -d ${CURDIR}/base/toolchain/pocketbook-toolchain ]; then
|
||||
make pocketbook-toolchain
|
||||
fi
|
||||
make TARGET=pocketbook
|
||||
;;
|
||||
ubuntu-touch)
|
||||
make TARGET=ubuntu-touch
|
||||
;;
|
||||
win32)
|
||||
make TARGET=win32
|
||||
;;
|
||||
*)
|
||||
make
|
||||
setup_env
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
function kodev-clean {
|
||||
CLEAN_HELP_MSG="
|
||||
usage: clean <TARGET>
|
||||
|
||||
TARGET:
|
||||
${SUPPORTED_TARGETS}"
|
||||
|
||||
case $1 in
|
||||
-h | --help)
|
||||
echo "${CLEAN_HELP_MSG}"
|
||||
exit 0
|
||||
;;
|
||||
kindle)
|
||||
make TARGET=kindle clean
|
||||
;;
|
||||
kobo)
|
||||
make TARGET=kobo clean
|
||||
;;
|
||||
kindle-legacy)
|
||||
make TARGET=kindle-legacy clean
|
||||
;;
|
||||
android)
|
||||
make TARGET=android clean
|
||||
;;
|
||||
pocketbook)
|
||||
make TARGET=pocketbook clean
|
||||
;;
|
||||
ubuntu-touch)
|
||||
make TARGET=ubuntu-touch clean
|
||||
;;
|
||||
win32)
|
||||
make TARGET=win32 clean
|
||||
;;
|
||||
*)
|
||||
make clean
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
function kodev-release {
|
||||
# SUPPORTED_RELEASE_TARGETS=$(echo ${SUPPORTED_TARGETS} | sed 's/win32//')
|
||||
SUPPORTED_RELEASE_TARGETS="${SUPPORTED_TARGETS/emu*/""}"
|
||||
RELEASE_HELP_MSG="
|
||||
usage: release <TARGET>
|
||||
|
||||
TARGET:
|
||||
${SUPPORTED_RELEASE_TARGETS}"
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "${RELEASE_HELP_MSG}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
-h | --help)
|
||||
echo "${RELEASE_HELP_MSG}"
|
||||
exit 0
|
||||
;;
|
||||
kindle)
|
||||
kodev-build kindle
|
||||
make TARGET=kindle update
|
||||
;;
|
||||
kobo)
|
||||
kodev-build kobo
|
||||
make TARGET=kobo update
|
||||
;;
|
||||
kindle-legacy)
|
||||
kodev-build kindle-legacy
|
||||
make TARGET=kindle-legacy update
|
||||
;;
|
||||
android)
|
||||
kodev-build android
|
||||
make TARGET=android update
|
||||
;;
|
||||
pocketbook)
|
||||
kodev-build pocketbook
|
||||
make TARGET=pocketbook update
|
||||
;;
|
||||
ubuntu-touch)
|
||||
kodev-build pocketbook
|
||||
make TARGET=ubuntu-touch update
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported target for release: $1."
|
||||
echo "${RELEASE_HELP_MSG}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
function kodev-wbuilder {
|
||||
kodev-build
|
||||
echo "[*] Running wbuilder.lua..."
|
||||
pushd ${EMU_DIR}
|
||||
EMULATE_READER_W=540 EMULATE_READER_H=720 ./luajit ./utils/wbuilder.lua
|
||||
popd
|
||||
}
|
||||
|
||||
function kodev-run {
|
||||
RUN_HELP_MSG="
|
||||
usage: run <OPTIONS> <ARGS>
|
||||
|
||||
OPTIONS:
|
||||
|
||||
--no-build run reader without rebuilding
|
||||
--disable-touch use this if you want to simulate keyboard only devices
|
||||
"
|
||||
while [[ $1 == '--'* ]]; do
|
||||
PARAM=`echo $1 | awk -F= '{print $1}'`
|
||||
VALUE=`echo $1 | awk -F= '{print $2}'`
|
||||
case $PARAM in
|
||||
--disable-touch)
|
||||
export DISABLE_TOUCH=1
|
||||
;;
|
||||
--no-build)
|
||||
no_build=true
|
||||
;;
|
||||
-h | --help)
|
||||
echo "${RUN_HELP_MSG}"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown option \"$PARAM\""
|
||||
echo "${RUN_HELP_MSG}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ ! ${no_build} ]; then
|
||||
echo "[*] Building KOReader..."
|
||||
kodev-build
|
||||
else
|
||||
setup_env
|
||||
fi
|
||||
|
||||
echo "[*] Running KOReader..."
|
||||
pushd ${EMU_DIR}
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
args=${CURDIR}/test
|
||||
else
|
||||
args="$1"
|
||||
[[ $args != /* ]] && args="${CURDIR}/$1"
|
||||
fi
|
||||
|
||||
EMULATE_READER_W=540 EMULATE_READER_H=720 ./reader.lua -d $args
|
||||
popd
|
||||
}
|
||||
|
||||
HELP_MSG="
|
||||
usage: $0 COMMAND <ARGS>
|
||||
|
||||
Supported commands:
|
||||
|
||||
build Build KOReader
|
||||
clean Clean KOReader build
|
||||
run Run KOReader
|
||||
wbuilder Run wbuilder.lua script (useful for building new UI widget)
|
||||
"
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Missing command."
|
||||
echo "${HELP_MSG}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
fetch-thirdparty)
|
||||
kodev-fetch-thirdparty
|
||||
;;
|
||||
clean)
|
||||
shift 1
|
||||
kodev-clean $@
|
||||
;;
|
||||
build)
|
||||
shift 1
|
||||
kodev-build $@
|
||||
;;
|
||||
release)
|
||||
shift 1
|
||||
kodev-release $@
|
||||
;;
|
||||
wbuilder)
|
||||
kodev-wbuilder
|
||||
;;
|
||||
run)
|
||||
shift 1
|
||||
kodev-run $@
|
||||
;;
|
||||
--help | -h)
|
||||
echo "${HELP_MSG}"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command: $1."
|
||||
echo "${HELP_MSG}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -235,7 +235,7 @@ function ReaderStatistics:updateCurrentStat()
|
||||
dates[os.date("%Y-%m-%d", k)] = ""
|
||||
end
|
||||
|
||||
local read_pages = util.tablelength(self.data.performance_in_pages)
|
||||
local read_pages = util.tableSize(self.data.performance_in_pages)
|
||||
local current_page = self.ui.document:getCurrentPage()
|
||||
local average_time_per_page = self.data.total_time_in_sec / read_pages
|
||||
|
||||
@@ -244,7 +244,7 @@ function ReaderStatistics:updateCurrentStat()
|
||||
table.insert(stats, { text = _("Total time"), mandatory = util.secondsToClock(self.data.total_time_in_sec, false) })
|
||||
table.insert(stats, { text = _("Total highlights"), mandatory = self.data.highlights })
|
||||
table.insert(stats, { text = _("Total notes"), mandatory = self.data.notes })
|
||||
table.insert(stats, { text = _("Total days"), mandatory = util.tablelength(dates) })
|
||||
table.insert(stats, { text = _("Total days"), mandatory = util.tableSize(dates) })
|
||||
table.insert(stats, { text = _("Average time per page"), mandatory = util.secondsToClock(average_time_per_page, false) })
|
||||
table.insert(stats, { text = _("Read pages/Total pages"), mandatory = read_pages .. "/" .. self.data.pages })
|
||||
return stats
|
||||
|
||||
@@ -34,10 +34,13 @@ local TouchMenu = require("ui/widget/touchmenu")
|
||||
local InputText = require("ui/widget/inputtext")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local ReaderUI = require("apps/reader/readerui")
|
||||
local Dbg = require("dbg")
|
||||
local DEBUG = require("dbg")
|
||||
local Device = require("device")
|
||||
local Screen = require("device").screen
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local InputText = require("ui/widget/inputtext")
|
||||
|
||||
DEBUG:turnOn()
|
||||
|
||||
-----------------------------------------------------
|
||||
-- widget that paints the grid on the background
|
||||
@@ -260,9 +263,8 @@ readerwindow = CenterContainer:new{
|
||||
reader = ReaderUI:new{
|
||||
dialog = readerwindow,
|
||||
dimen = Geom:new{ w = Screen:getWidth() - 100, h = Screen:getHeight() - 100 },
|
||||
document = DocumentRegistry:openDocument("test/2col.pdf")
|
||||
--document = DocumentRegistry:openDocument("test/djvu3spec.djvu")
|
||||
--document = DocumentRegistry:openDocument("./README.TXT")
|
||||
document = DocumentRegistry:openDocument("spec/front/unit/data/2col.pdf")
|
||||
--document = DocumentRegistry:openDocument("spec/front/unit/data/djvu3spec.djvu")
|
||||
}
|
||||
readerwindow[1][1] = reader
|
||||
|
||||
@@ -341,9 +343,14 @@ touch_menu = TouchMenu:new{
|
||||
},
|
||||
}
|
||||
|
||||
inputtext = InputText:new{
|
||||
local TestInputText = InputText:new{
|
||||
width = 400,
|
||||
height = 300,
|
||||
enter_callback = function() print("Entered") end,
|
||||
scroll = false,
|
||||
input_type = "number",
|
||||
parent = {
|
||||
onSwitchFocus = false,
|
||||
},
|
||||
}
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
@@ -358,6 +365,7 @@ UIManager:show(Clock:new())
|
||||
--UIManager:show(readerwindow)
|
||||
--UIManager:show(touch_menu)
|
||||
--UIManager:show(keyboard)
|
||||
-- UIManager:show(inputtext)
|
||||
UIManager:show(TestInputText)
|
||||
TestInputText:onShowKeyboard()
|
||||
|
||||
UIManager:run()
|
||||
Reference in New Issue
Block a user