Post by warspyking on Jan 5, 2016 13:49:01 GMT
This is a fully functional keyboard with a working display. It's keyboard IS customizable, so if you don't need all the stuff I put in the default, you can remove it. Less rows/less buttons in the biggest row makes the buttons bigger and less cumbersome to hit.
Here's the code:
Here's the code:
local Keyboard,Key,Text,Display
do
do
do
Keyboard = {}
Keyboard.Board = {}
Keyboard.Handler = {}
Keyboard.Internal = {
Visible = false,
Capitals = false,
Shift = false
}
function Keyboard.new(self,keys,key,beg, fin,w,h,tw,th)
local new = setmetatable({
Board = {},
Handler = {
Begin = beg,
End = fin,
},
Internal = {
Typed = {{}},
Rows = #keys,
Width = w or 100,
Height = h or 100,
ScreenWidth = tw or 100,
ScreenHeight = th or 100
}
},{
__index = self
})
for i,r in ipairs(keys) do
local newr = {}
for ii,k in ipairs(r) do
newr[ii] = key:new(k,newr,new)
end
new.Board[i] = newr
end
return new
end
function Keyboard.SendInput(self, key, beg)
self.Handler[beg and 'Begin' or 'End'](key)
end
function Keyboard.SetHeight(self, h)
self.Internal.Height = h
end
function Keyboard.Show(self)
self.Internal.Visible = true
end
function Keyboard.Hide(self)
self.Internal.Visible = false
end
function Keyboard.Draw(self)
local max = {table.unpack(self.Board)}
table.sort(max,function(a,b) return #a >= #b end)
local w = self.Internal.Width/#max[1]
draw.fillrect(0,self.Internal.ScreenHeight-self.Internal.Height,self.Internal.Width,self.Internal.ScreenHeight,draw.darkgray)
for i,r in ipairs(self.Board) do
local offset = (self.Internal.Width-#r*w)/2
for ii,k in ipairs(r) do
local size,position = {},{}
size.x = w
size.y = self.Internal.Height/self.Internal.Rows
position.x = (size.x*ii-size.x/2)+offset
position.y = self.Internal.ScreenHeight-self.Internal.Height+(size.y*i-size.y/2)
k:Draw(size,position,self.Internal.Capitals)
end
end
end
do
Key = {}
Key.Special = {
BACK= {
Name = 'BK',
Full = 'BACK',
Value = -1,
Execute = function(self, key)
local typed = key.Parent.Internal.Typed
if #typed[#typed] > 0 then
typed[#typed][#typed[#typed]] = nil
elseif #typed > 1 then
typed[#typed] = nil
end
end
},
SHIFT = {
Name = 'UP',
Full = 'SHIFT',
Value= -2,
Execute = function(self,key)
key.Parent.Internal.Shift = not key.Parent.Internal.Shift
end
},
LOCK={
Name = 'LK',
Full = 'LOCK',
Value = -3,
Execute = function(self,key)
key.Parent.Internal.Capitals = not key.Parent.Internal.Capitals
end
},
RETURN = {
Name="RT",
Full = 'RETURN',
Value= -4,
Execute = function(self,key)
key.Parent.Internal.Typed[#key.Parent.Internal.Typed+1] = {}
end
}
}
Key.Name = "0"
Key.Value = 32
Key.IsPressed = false
Key.State = "up"
function Key.new(self, key, row, par)
local special = self.Special[key] or {Name=key,Full=key,Value=string.byte(key)}
return setmetatable({
Name = special.Name,
Full = special.Full,
Value = special.Value,
Row = row,
Parent = par
},{
__index=self,
__tostring=function(t)
return t.Name
end
})
end
function Key.BeginPress(self)
self.Parent:SendInput(self,true)
end
function Key.EndPress(self)
self.Parent:SendInput(self,false)
end
function Key.Draw(self, size, pos, caps)
draw.rect(pos.x-size.x/2,pos.y-size.y/2,pos.x+size.x/2,pos.y+size.y/2,draw.gray)
draw.fillrect(pos.x-size.x/2,pos.y-size.y/2,pos.x+size.x/2,pos.y+size.y/2,draw.lightgray)
draw.stringinrect(string[caps and 'upper' or 'lower'](self.Name), pos.x-size.x/2,pos.y-size.y/2,pos.x+size.x/2,pos.y+size.y/2,draw.black)
end
end
end
end
do
do
Text = {}
Text.Font = 'Helvetica'
Text.Size = 14
Text.Color = draw.black
Text.Text = ''
function Text.new(self,text)
return setmetatable({Text=text},{__index=self,__tostring=function(t)return t.Text end})
end
end
do
Display = {}
Display.Content = {{}}
Display.Visible = false
Display.ScreenWidth = 100
Display.ScreenHeight = 100
function Display.new(self,tw,th)
return setmetatable({
Content = {{}},
ScreenWidth = tw or 100,
ScreenHeight = th or 100
}, {
__index = self
})
end
function Display.SetContent(self,content)
self.Content = content
end
function Display.Compress(self)
--
end
function Display.Show(self)
self.Visible = true
end
function Display.Hide(self)
self.Visible = false
end
function Display.Draw(self)
local sizes = {}
local y = 0
for i,l in ipairs(self.Content) do
sizes[i] = {width={},height={}}
local x = 0
for ii,c in ipairs(l) do
draw.setfont(c.Font, c.Size)
sizes[i].width[ii],sizes[i].height[ii] = draw.stringsize(c.Text)
draw.string(c.Text, x,y,c.Color)
x = x + sizes[i].width[ii]
end
y = y + math.max(table.unpack(sizes[i].height) or 0)
end
end
end
end
end
--------------------------------------------
draw.setscreen(1)
draw.settitle("Keyboard")
local width,height = draw.getport()
local keyboard = Keyboard:new(
{
{'1','2','3','4','5','6','7','8','9','0'},
{'q','w','e','r','t','y','u','i','o','p'},
{'a','s','d','f','g','h','j','k','l'},
{'z','x','c','v','b','n','m'},
{'+','-','*','/','^','%','#','=','<','>','~'},
{':','(',')','{','}','[',']','\'',',','.',' '},
{'BACK','SHIFT','LOCK','RETURN'}
},
Key,
function(key)
--
end,
function(key)
if key.Special[key.Full] then
key.Special[key.Full]:Execute(key)
else
local typed = key.Parent.Internal.Typed
if key.Parent.Internal.Shift or key.Parent.Internal.Capitals then
typed[#typed][#typed[#typed]+1] = Text:new(key.Name:upper())
key.Parent.Internal.Shift = false
else
typed[#typed][#typed[#typed]+1] = Text:new(key.Name:lower())
end
end
end,
width,height/3,width,height
)
local display = Display:new(width,height)
keyboard:Show()
display:Show()
--------------------------------------------
draw.tracktouches(
function(x,y)
end,
function(x,y)
end,
function(x,y)
local screenwidth, screenheight, keyboardwidth, keyboardheight = keyboard.Internal.ScreenWidth, keyboard.Internal.ScreenHeight, keyboard.Internal.Width, keyboard.Internal.Height
if y > screenheight-keyboardheight then
local yoffset = y - (screenheight-keyboardheight)
local rows = keyboard.Internal.Rows
local row = keyboard.Board[math.floor((yoffset-1)/(keyboardheight/rows))+1]
local numbers = {}
for i,v in ipairs(keyboard.Board) do
numbers[#numbers+1] = #v
end
local bwidth = keyboardwidth/math.max(table.unpack(numbers))
local rwidth = #row*bwidth
local xoffset = x-(screenwidth-rwidth)/2
local col = math.floor((xoffset-1)/(rwidth/#row))+1
if row[col] then
row[col]:EndPress()
end
end
end
)
--------------------------------------------
while true do
sleep(100)
draw.clear()
draw.beginframe()
if keyboard.Internal.Visible then
keyboard:Draw()
end
if display.Visible then
display:SetContent(keyboard.Internal.Typed)
display:Draw()
end
draw.endframe()
draw.doevents()
end