Improve Zictionary scene so we don't need to hyper tapping much than before (#926)

* Attempt to rework Zictionary scene

* Rearrange the layout and handling most of thing

* Remove ALPHA key, done keyboard handling, changed some key's behavior

* Add Help text

* Update Help text & fix some bugs

* Update help text

* Edit help text

* Support gamepad

* small changes in help text

* small changes

* Fix copy bug

* small change

* Add hint text to open Hint

* Fix a bug that item accidentally selected when scrolling

* Clean up a dumb function
(Forget to cleanup in previous commit)

* add backup solution, just in case

* fix another bug

* fix touch bug

* Refix the scroll bug when touch

* small code changes

* small change in English file
This commit is contained in:
C6H12O6 + NaCl + H2O
2023-07-31 02:20:24 +07:00
committed by GitHub
parent 4d82b182a6
commit 9d3fb33d10
3 changed files with 346 additions and 91 deletions

View File

@@ -16,7 +16,7 @@ return {
{"Practice Recommendations", {"Practice Recommendations",
"readme noob new guides recommendations suggestions helps", "readme noob new guides recommendations suggestions helps",
"help", "help",
"Here are our recommendations for improving your Tetris skills. If you have ever felt difficulties in your training, you can just relax and spend some time playing the modes you do enjoy. Have fun!\n\nThese are sets of missions that you need to accomplish. When there is order within each set, we recommend you to do all three sets of tasks simultaneously instead of one by one.\n\nA. Stacking\n\tA1. Think twice before you place your block. If your first decision doesnt seem to fit well, think again.\n\tA2. Keep your terrain flat since it allows more possibilities for different blocks.\n\tA3. When hold allowed, thinking more about sequences to arrange the pieces in your hand, the held one, plus the previews. In order to have flat terrain for longer time.\nB. Efficiency & Speed\n\tB1. Dont count on ghost pieces. Think, with your brain, where this piece would land and what keys you should press. Do it only when you are ready.\n\tB2. Use both of the rotation keys. Dont just use one and press it many times when you can press the other one just once.\n\tB3. Dont worry too much about your speed when you start learning Finesse. Keep your move accurate, and then it is not hard to improve your speed once you have mastered it.\nC. Stacking\n\tC1. Finish 40L without topping out.\n\tC2. Finish 40L with no Hold without topping out.\n\tC3. Finish 40L with all Techrashes.\n\tC4. Finish 40L with all Techrashes and no Hold.\n\nSet C is more flexible, and you can adjust the difficulties based on your own conditions (like what does ” means to you).\n\nWhen you finish all the tasks in set C, keep practicing A1. This is the fundamental skill in any Tetris game, and you can master practically any mode when you can just scan through the Next sequence easily.", "Here are our recommendations for improving your Tetris skills. If you have ever felt difficulties in your training, you can just relax and spend some time playing the modes you do enjoy. Have fun!\n\nThese are sets of missions that you need to accomplish. When there is order within each set, we recommend you to do all three sets of tasks simultaneously instead of one by one.\n\nA. Stacking\n\tA1. Think twice before you place your block. If your first decision doesnt seem to fit well, think again.\n\tA2. Keep your terrain flat since it allows more possibilities for different blocks.\n\tA3. When hold allowed, thinking more about sequences to arrange the pieces in your hand, the held one, plus the previews. In order to have flat terrain for longer time.\nB. Efficiency & Speed\n\tB1. Dont count on ghost pieces. Think, with your brain, where this piece would land and what keys you should press. Do it only when you are ready.\n\tB2. Use both of the rotation keys. Dont just use one and press it many times when you can press the other one just once.\n\tB3. Dont worry too much about your speed when you start learning Finesse. Keep your move accurate, and then it is not hard to improve your speed once you have mastered it.\nC. Stacking\n\tC1. Finish 40L without topping out.\n\tC2. Finish 40L with no Hold without topping out.\n\tC3. Finish 40L with all Techrashes.\n\tC4. Finish 40L with all Techrashes and no Hold.\n\nSet C is more flexible, and you can adjust the difficulties based on your own conditions (like what does “stably” means to you).\n\nWhen you finish all the tasks in set C, keep practicing A1. This is the fundamental skill in any Tetris game, and you can master practically any mode when you can just scan through the Next sequence easily.",
}, },
{"Learning T-spins", {"Learning T-spins",
"tspins learning study guides tips recommendations suggestions helps", "tspins learning study guides tips recommendations suggestions helps",

View File

@@ -378,6 +378,64 @@ return {
sha2 [Egor Skriptunoff] sha2 [Egor Skriptunoff]
]], ]],
support="Support the author", support="Support the author",
dict={
sizeChanged="Changed font size: $1",
sizeReset="Reset font size: 25",
helpText=
[[
ZICTIONARY NAVIGATION INSTRUCTION
NOTE: Some functions may not have specific gestures for gamepad input.
In such cases, you can use alternative input methods or follow the provided instructions.
Scrolling text:
Keyboard: Use [$1] to scroll up, [$2] to scroll down.
Gamepad: Use $5 to scroll up, $6 to scroll down.
Mouse/Touch screen: Use the familiar scrolling gestures.
Exiting Zictionary:
Keyboard: Press [Esc] key.
Gamepad: Press [BACK] button.
Mouse/Touch screen: Press the Back button in the top right corner of the screen.
Opening/closing Help:
Keyboard: Press [F1] key.
Gamepad: Press $10 key.
Mouse/Touch screen: Tap [$13] key.
Opening previous/next item in the list:
Keyboard: Press [$3] to open the previous item, [$4] to open the next one.
Gamepad: Press $7 to open the previous item, $8 to open the next one.
Mouse/Touch screen: Click/touch the item below the currently selected one in the list.
Jumping backward/forward through 12 items:
Keyboard: Hold [Ctrl]/[Shift]/[Alt] key first, then press [$3] to jump backward, [$4] to jump forward.
Gamepad: Hold $11 key first, then press $7 to jump backward, and $8 to jump forward.
Mouse/Touch screen: Click/Touch [$16] to jump backward, [$17] to jump forward
Changing font size (DEFAULT: 25):
Keyboard: Hold Ctrl key first, then press [-] to make the text smaller, [+] to make it bigger, [0] to reset the font size to default.
Gamepad: Hold $11 key first, then press $6 to make the text smaller, and $5 to make it bigger.
Mouse/Touch screen:
Press [aA] to show [a] and [A] buttons.
Click/touch [a] to make the text smaller.
Click/touch [A] to make the text bigger.
To reset the font size, wait for 3 seconds for [aA] [100%] to reappear, then click/touch [100%] to reset.
Note: There's no gesture to reset the font size with the Gamepad, but you can set it back to 25.
Copying the content:
Keyboard: Press [Ctrl] + [C].
Mouse/Touch screen: Press [$14] key.
Opening item's URL (if available):
Keyboard: Press [$18] (Context menu/Application key).
Mouse/Touch screen: Press [$15] key.
]]
-- 1-4: Up, Down, Left, Right
-- 5-8: Up, Down, Left, Right but D-Pad
-- 9-12: X, Y, A, B
-- 13-18: Help, Copy, Open, Forward, Backward, MENU
},
WidgetText={ WidgetText={
main={ main={
offline="Single Player", offline="Single Player",

View File

@@ -1,6 +1,5 @@
local gc=love.graphics local gc=love.graphics
local inputBox=WIDGET.newInputBox{name='input',x=20,y=110,w=762,h=60,font=40,limit=32}
local int,abs=math.floor,math.abs local int,abs=math.floor,math.abs
local min,sin=math.min,math.sin local min,sin=math.min,math.sin
local ins=table.insert local ins=table.insert
@@ -13,10 +12,17 @@ local result-- Result Lable
local lastTickInput local lastTickInput
local searchWait-- Searching animation timer local searchWait-- Searching animation timer
local selected-- Selected option
local scrollPos-- Scroll down length
local lastSearch-- Last searched string local lastSearch-- Last searched string
local lastSelected -- Last selected item
local justSearched -- Just searched or not?
local currentFontSize=25 -- Current font size, default: 25
local showingHelp=false -- Help is triggered or not
local zoomWait=0 -- The last time zoom is triggered
local oldScrollPos=0
local lastMouseX,lastMouseY,lastTouchX,lastTouchY
local typeColor={ local typeColor={
help=COLOR.Y, help=COLOR.Y,
@@ -29,9 +35,11 @@ local typeColor={
english=COLOR.B, english=COLOR.B,
name=COLOR.lV, name=COLOR.lV,
} }
-- Scan the dictionary and return the list
local function _filter(word_org) local function _filter(word_org)
local word=word_org local word=word_org
word=word:gsub("[Tt]etris",CHAR.zChan.thinking) word=word:gsub("[Tt][Ee][Tt][Rr][Ii][Ss]",CHAR.zChan.thinking)
if FNNS then word=word:gsub("[Pp]\97\116\114\101\111\110",CHAR.zChan.qualified) end if FNNS then word=word:gsub("[Pp]\97\116\114\101\111\110",CHAR.zChan.qualified) end
return word,word_org return word,word_org
end end
@@ -49,23 +57,44 @@ local function _scanDict(D)
end end
end end
local function _getList() return result[1] and result or dict end local function _getList() return result[1] and result or dict end
-- Drawing objects
local infoBox =WIDGET.newTextBox {name='infoBox',x=320,y=180,w=862,h=526,font=25,fix=true}
local inputBox=WIDGET.newInputBox{name='input', x=20, y=110,w=762,h=60, font=40,limit=32}
local listBox =WIDGET.newListBox {name='listBox',x=20, y=180,w=280,h=526,font=30,lineH=35,drawF=function(item,id,ifSel)
-- Draw list box
-- Background
if ifSel then
gc.setColor(1,1,1,.4)
gc.rectangle('fill',0,0,280,35)
end
-- Name & color
local item=_getList()[id]
GC.shadedPrint(item.title,10,-3,'left',1,COLOR.D,typeColor[item.type])
-- Draw list box /
end}
-- Drawing object /
-- Necessary local functions
-- Clear the result
local function _clearResult() local function _clearResult()
TABLE.cut(result) TABLE.cut(result)
selected=1 listBox.selected=1
scrollPos=0 justSearched=true
searchWait,lastSearch=0,false searchWait,lastSearch=0,false
scene.widgetList.copy.hide=false scene.widgetList.copy.hide=false
end end
-- Search through the dictionary
local function _search() local function _search()
local input=inputBox:getText():lower() local input=inputBox:getText():lower()
_clearResult() _clearResult()
-- This change was made by Sea. Should the search function prioritize the best match result and move it to the top of the search result
-- Usually yes except Vietnamese version of Zictionary
local prioritizeBestMatch=not SETTING.locale:find"vi"
local first local first
for i=1,#dict do for i=1,#dict do
local pos=find(dict[i].title:lower(),input,nil,true) or find(dict[i].keywords:lower(),input,nil,true) local pos=find(dict[i].title:lower(),input,nil,true) or find(dict[i].keywords:lower(),input,nil,true)
if pos==1 and not first and prioritizeBestMatch then if pos==1 and not first then
ins(result,1,dict[i]) ins(result,1,dict[i])
first=true first=true
elseif pos then elseif pos then
@@ -74,10 +103,115 @@ local function _search()
end end
if #result>0 then if #result>0 then
SFX.play('reach') SFX.play('reach')
justSearched=true
end end
lastSearch=input lastSearch=input
end end
-- Jump over n items
local function _jumpover(key,n)
n=n or 1
if key=='left' or key=='pageup' then
for _=1,n do scene.widgetList.listBox:arrowKey('up') end
else for _=1,n do scene.widgetList.listBox:arrowKey('down') end end
end
-- Copy the content
local function _copy()
local t=_getList()[listBox.selected]
t=t.title_Org..":\n"..t.content_Org..(t.url and "\n[ "..t.url.." ]\n" or "\n")..text.dictNote
love.system.setClipboardText(t)
scene.widgetList.copy.hide=true
MES.new('info',text.copyDone)
end
-- Update the infobox
local function _updateInfoBox(c)
local _t,t
if c==nil then
if showingHelp then
if text.dict.helpText then
t,_t=text.dict.helpText:repD(
CHAR.key.up, CHAR.key.down, CHAR.key.left, CHAR.key.right,
CHAR.controller.xboxX, CHAR.controller.xboxY, CHAR.controller.xboxA, CHAR.controller.xboxB,
CHAR.icon.help, CHAR.icon.copy, CHAR.icon.globe,
CHAR.icon.toUp, CHAR.icon.toDown, CHAR.key.winMenu
),true
else _t,t=true,{"NO HELP TEXT AVAILABLE!\n","Please switch language to English and try again to read the help text"} end
else _t,t=pcall(function() return _getList()[listBox.selected].content end) end
if _t then c=t else c={""} end
_t,t=nil,nil
end
local _w,c=FONT.get(currentFontSize):getWrap(c,840)
infoBox:setTexts(c)
end
-- Show Help or not
local function _toggleHelp()
local listBox = scene.widgetList.listBox
showingHelp = not showingHelp
if not showingHelp then
listBox.selected=lastSelected
scene.widgetList.copy.hide=false
end
_updateInfoBox()
end
-- Zoom and reset zoom
local function _openZoom() zoomWait=2 end
local function _resetZoom()
currentFontSize,infoBox.font=25,25
infoBox.lineH,infoBox.capacity=35,math.ceil((infoBox.h-10)/35)
_updateInfoBox()
MES.new("check",text.dict.sizeReset,1.26)
end
local function _setZoom(z)
if z~=0 then
currentFontSize=MATH.clamp(currentFontSize+z,15,40)
infoBox.font=currentFontSize
infoBox.lineH=currentFontSize*7/5 -- Recalculate the line's height
infoBox.capacity=math.ceil((infoBox.h-10)/infoBox.lineH)
_updateInfoBox()
_openZoom()
MES.new("check",text.dict.sizeChanged:repD(currentFontSize),1.26)
end
end
-- Checking if waiting countdown reach 0 to run the function.
--
-- currentCountdown: the variable that tracking waiting time
-- timeEndF: run this function if the time reach 0
-- nTimeEndF: run this function if the time has not reached 0
--
-- NOTE: This function will return the modified value of currentcountdown
local function _waitingfor(currentcountdown, timeEndF, nTimeEndF)
currentcountdown = currentcountdown or 0
timeEndF = timeEndF or function() end
nTimeEndF= nTimeEndF or function() end
if currentcountdown>0 then
currentcountdown=currentcountdown-love.timer.getDelta()
if currentcountdown<=0 then timeEndF() else nTimeEndF() end
end
return currentcountdown
end
local function fixScrollingByTouch(x,y,lastX,lastY)
if WIDGET.isFocus(listBox) then
if abs(oldScrollPos-listBox.scrollPos)>26 then
oldScrollPos=listBox.scrollPos
listBox.selected=lastSelected
listBox.scrollPos=oldScrollPos
else
lastSelected=listBox.selected
scene.widgetList.copy.hide=false
_updateInfoBox()
end
end
end
-- Reset everything when opening Zictionary
function scene.enter() function scene.enter()
dict=require("parts.language.dict_"..(SETTING.locale:find'zh' and 'zh' or SETTING.locale:find'ja' and 'ja' or SETTING.locale:find'vi' and 'vi' or 'en')) dict=require("parts.language.dict_"..(SETTING.locale:find'zh' and 'zh' or SETTING.locale:find'ja' and 'ja' or SETTING.locale:find'vi' and 'vi' or 'en'))
_scanDict(dict) _scanDict(dict)
@@ -85,12 +219,14 @@ function scene.enter()
inputBox:clear() inputBox:clear()
result={} result={}
searchWait=0 if showingHelp then _toggleHelp() end
selected=1
scrollPos=0
searchWait=0
lastSelected=0
listBox.selected=1
lastSearch=false lastSearch=false
WIDGET.focus(inputBox)
if not MOBILE then WIDGET.focus(inputBox) end
BG.set('rainbow') BG.set('rainbow')
end end
@@ -98,57 +234,95 @@ function scene.wheelMoved(_,y)
WHEELMOV(y) WHEELMOV(y)
end end
function scene.keyDown(key) function scene.keyDown(key)
if key=='up' then -- Switching selected items
if selected and selected>1 then if key=='up' or key=='down' then
selected=selected-1 if not showingHelp then
if selected<scrollPos+1 then if love.mouse.isDown(2,3) then
scrollPos=scrollPos-1 listBox:arrowKey(key)
return
elseif WIDGET.isFocus(listBox) then
listBox:scroll(key=='up' and -1 or 1)
return
end end
scene.widgetList.copy.hide=false
end end
elseif key=='down' then infoBox:scroll(key=='up' and -3 or 3)
if selected and selected<#_getList() then
selected=selected+1 elseif (key=='left' or key=='pageup' or key=='right' or key=='pagedown')
if selected>scrollPos+15 then then
scrollPos=selected-15 if love.keyboard.isDown('lctrl','rctrl','lalt','ralt','lshift','rshift')
then _jumpover(key,12)
else _jumpover(key,1)
end end
scene.widgetList.copy.hide=false
end -- Copy & Zoom
elseif key=='left' or key=='pageup' then elseif key=='cC' then _copy()
for _=1,12 do scene.keyDown('up') end elseif love.keyboard.isDown('lctrl','rctrl') then
elseif key=='right' or key=='pagedown' then if key == 'c' and not showingHelp then _copy() return
for _=1,12 do scene.keyDown('down') end elseif love.keyboard.isDown('-','=','kp-','kp+') then _setZoom((key=='-' or key=='kp-') and -5 or 5)
elseif key=='application' then elseif love.keyboard.isDown('0','kp0') then _resetZoom() end
local url=_getList()[selected].url
-- Clear search input, open URL
elseif key=='application' and not showingHelp then
local url=_getList()[listBox.selected].url
if url then love.system.openURL(url) end if url then love.system.openURL(url) end
elseif key=='delete' then elseif key=='delete' and not showingHelp then
if inputBox:hasText() then if inputBox:hasText() then
_clearResult() _clearResult()
inputBox:clear() inputBox:clear()
SFX.play('hold') SFX.play('hold')
end end
-- Get out of Zictionary
elseif key=='escape' then elseif key=='escape' then
if inputBox:hasText() then if inputBox:hasText() then scene.keyDown('delete')
scene.keyDown('delete') elseif showingHelp then _toggleHelp()
else else SCN.back()
SCN.back()
end end
elseif key=='c' and love.keyboard.isDown('lctrl','rctrl') or key=='cC' then -- Calling Help
local t=_getList()[selected] elseif key=='f1' then _toggleHelp()
t=t.title_Org..":\n"..t.content_Org..(t.url and "\n[ "..t.url.." ]\n" or "\n")..text.dictNote -- Focus on the search box
love.system.setClipboardText(t)
scene.widgetList.copy.hide=true
MES.new('info',text.copyDone)
return
else else
if not WIDGET.isFocus(inputBox) then if not WIDGET.isFocus(inputBox) then WIDGET.focus(inputBox) end
WIDGET.focus(inputBox)
end
return true return true
end end
end end
function scene.gamepadDown(key)
local Joystick=love.joystick.getJoysticks()[love.joystick.getJoystickCount()]
-- Scrolling text & zooming
if (key=='dpup' or key=='dpdown') then
if Joystick:isGamepadDown('a')
then _setZoom(key=='dpup' and 5 or -5)
else infoBox:scroll(key=='dpup' and -3 or 3)
end
-- Switching selected items
elseif key=='dpleft' or key=='dpright' then
_jumpover(key:gsub('dp',''),Joystick:isGamepadDown('a') and 12 or 1)
-- Activate help
elseif key=='y' then _toggleHelp()
-- Exit
elseif key=='back' then SCN.back()
end
end
function scene.mouseDown(mx,my)
lastMouseX,lastMouseY=mx,my
end
function scene.touchDown(mx,my)
lastTouchX,lastTouchY=mx,my
end
-- Check if left mouse key is released
function scene.mouseUp(mx,my)
fixScrollingByTouch(mx,my,lastMouseX,lastMouseY)
end
function scene.touchUp(mx,my)
fixScrollingByTouch(mx,my,lastTouchX,lastTouchY)
end
function scene.update(dt) function scene.update(dt)
-- It's time to search?
local input=inputBox:getText() local input=inputBox:getText()
if input~=lastTickInput then if input~=lastTickInput then
if #input==0 then if #input==0 then
@@ -158,53 +332,62 @@ function scene.update(dt)
end end
lastTickInput=input lastTickInput=input
end end
if searchWait>0 then searchWait=_waitingfor(
searchWait=searchWait-dt searchWait,
if searchWait<=0 then function() if #input>0 and input~=lastSearch then _search() end end
if #input>0 and input~=lastSearch then )
_search() -- It's time to swap zoom buttons?
end zoomWait=_waitingfor(
zoomWait,
function()
scene.widgetList.openzoom .hide=false
scene.widgetList.resetzoom.hide=false
scene.widgetList.zoomin .hide=true
scene.widgetList.zoomout .hide=true
end,
function()
scene.widgetList.openzoom .hide=true
scene.widgetList.resetzoom.hide=true
scene.widgetList.zoomin .hide=false
scene.widgetList.zoomout .hide=false
end end
end )
end end
local function listStencil() local function listStencil()
GC.rectangle('fill',20,180,280,526) GC.rectangle('fill',20,180,280,526)
end end
function scene.draw() function scene.draw()
-- Order: list, info, keys
-- Draw background
gc.setColor(COLOR.dX) gc.setColor(COLOR.dX)
gc.rectangle('fill',300,180,958,526,5) gc.rectangle('fill',1194,180,80,526,5) -- keys
gc.rectangle('fill',20,180,280,526,5) -- Draw outline
gc.setLineWidth(2) gc.setLineWidth(2)
gc.setColor(COLOR.Z) gc.setColor(COLOR.Z)
gc.rectangle('line',300,180,958,526,5) gc.rectangle('line',1194,180,80,526,5) -- keys
gc.rectangle('line',20,180,280,526,5) -- Draw key seperating outline
gc.rectangle('line',1194,260,80,1,0) -- A | B
gc.rectangle('line',1194,410,80,1,0) -- B | C
gc.rectangle('line',1194,560,80,1,0) -- C | D
local list=_getList() local list=_getList()
gc.setColor(COLOR.Z)
local t=list[selected].content
setFont(
#t>900 and 15 or
#t>600 and 20 or
#t>400 and 25 or
30
)
gc.printf(t,306,180,950)
setFont(30) setFont(30)
gc.setColor(1,1,1,.4+.05*sin(TIME()*12.6))
gc.rectangle('fill',20,143+35*(selected-scrollPos),280,35)
GC.stencil(listStencil) -- Showing Help?
GC.setStencilTest('equal',1) if showingHelp then
setFont(30) listBox.selected=0
for i=1,min(#list,15) do scene.widgetList.copy.hide,scene.widgetList.link.hide=true,true
local y=142+35*i -- If not then, check the selected item if it is changed or not?
i=i+scrollPos -- If yes, update lastSelected then update the textbox!
local item=list[i] elseif justSearched then
GC.shadedPrint(item.title,30,y,'left',1,COLOR.D,typeColor[item.type]) listBox:setList(_getList())
justSearched=false
elseif lastSelected~=listBox.selected and not love.mouse.isDown(1) then
_updateInfoBox()
lastSelected=listBox.selected
scene.widgetList.copy.hide=false
end end
GC.setStencilTest()
if searchWait>0 then if searchWait>0 then
local r=TIME()*2 local r=TIME()*2
@@ -215,16 +398,30 @@ function scene.draw()
end end
scene.widgetList={ scene.widgetList={
WIDGET.newText{name='book', x=20,y=15,font=70,align='L',fText=CHAR.icon.zBook}, WIDGET.newText {name='book', x=20, y=15, font=70,align='L',fText=CHAR.icon.zBook},
WIDGET.newText{name='title', x=100,y=15,font=70,align='L'}, WIDGET.newText {name='title', x=100, y=15, font=70,align='L'},
listBox,
inputBox, inputBox,
WIDGET.newKey{name='link', x=1120,y=655,w=80,font=55,fText=CHAR.icon.globe, code=pressKey'application',hideF=function() return not _getList()[selected].url end}, infoBox,
WIDGET.newKey{name='copy', x=1210,y=655,w=80,font=50,fText=CHAR.icon.copy, code=pressKey'cC'}, WIDGET.newKey {name='link', x=1234,y=600,w=60,font=45,fText=CHAR.icon.globe, code=pressKey'application',hideF=function() return not ((not (showingHelp or listBox.selected==0)) and _getList()[listBox.selected].url) end},
WIDGET.newKey{name='up', x=1120,y=475,w=80,font=50,fText=CHAR.key.up, code=pressKey'up',hide=not MOBILE}, WIDGET.newKey {name='copy', x=1234,y=670,w=60,font=40,fText=CHAR.icon.copy, code=pressKey'cC'},
WIDGET.newKey{name='down', x=1120,y=565,w=80,font=50,fText=CHAR.key.down, code=pressKey'down',hide=not MOBILE},
WIDGET.newKey{name='pageup', x=1210,y=475,w=80,font=50,fText=CHAR.icon.toUp, code=pressKey'pageup',hide=not MOBILE}, WIDGET.newKey {name='openzoom', x=1234,y=300,w=60,font=25,fText="aA", code=function() _openZoom() end,hide=false},
WIDGET.newKey{name='pagedown',x=1210,y=565,w=80,font=50,fText=CHAR.icon.toDown,code=pressKey'pagedown',hide=not MOBILE}, WIDGET.newKey {name='resetzoom',x=1234,y=370,w=60,font=25,fText="100%", code=function() _resetZoom() end,hide=false},
WIDGET.newButton{name='back', x=1165,y=60,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene}, WIDGET.newKey {name='zoomin', x=1234,y=300,w=60,font=40,fText="A", code=function() _setZoom(5) end,hide=true},
} WIDGET.newKey {name='zoomout', x=1234,y=370,w=60,font=40,fText="a", code=function() _setZoom(-5) end,hide=true},
WIDGET.newKey {name='pageup', x=1234,y=450,w=60,font=40,fText=CHAR.icon.toUp, hideF=function() return love.mouse.isDown(2,3) or showingHelp end,code=function() _jumpover('left') end},
WIDGET.newKey {name='pagedown', x=1234,y=520,w=60,font=40,fText=CHAR.icon.toDown,hideF=function() return love.mouse.isDown(2,3) or showingHelp end,code=function() _jumpover('right') end},
WIDGET.newKey {name='pageup1', x=1234,y=450,w=60,font=40,fText=CHAR.key.up, hideF=function() return not love.mouse.isDown(2,3) or showingHelp end,color="A"},
WIDGET.newKey {name='pagedown1',x=1234,y=520,w=60,font=40,fText=CHAR.key.down, hideF=function() return not love.mouse.isDown(2,3) or showingHelp end,color="A"},
WIDGET.newKey {name='help0', x=1234,y=220,w=60,font=40,fText=CHAR.icon.help, code=pressKey'f1',hideF=function() return showingHelp end},
WIDGET.newKey {name='help1', x=1234,y=220,w=60,font=40,fText=CHAR.icon.help, code=pressKey'f1',hideF=function() return not showingHelp end,color='lF'},
WIDGET.newButton{name='back', x=1165,y=60, w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
WIDGET.newText {name='buttontip',x=1274,y=110,w=762,h=60,font=40,align='R',fText=CHAR.controller.xboxY.."/[F1]: "..CHAR.icon.help}
}
-- NOTE: The gap between Link-Copy, Page, Zoom, Help is 60*1.5-10=80 :) The gap between 2 buttons in one group is 60+10=70
return scene return scene