about summary refs log tree commit diff stats
path: root/lua
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2023-06-08 14:44:45 -0400
committerelioat <elioat@tilde.institute>2023-06-08 14:44:45 -0400
commit5242a233f52394c58cb304c9a10b339553f4e71f (patch)
treebd318710e208654cb635eecd809f5530e849c56e /lua
parentf583009ffae825c66a9dda7838820d3a9f19adf1 (diff)
downloadtour-5242a233f52394c58cb304c9a10b339553f4e71f.tar.gz
*
Diffstat (limited to 'lua')
-rw-r--r--lua/keyboard.playdate.lua373
1 files changed, 373 insertions, 0 deletions
diff --git a/lua/keyboard.playdate.lua b/lua/keyboard.playdate.lua
new file mode 100644
index 0000000..bbde871
--- /dev/null
+++ b/lua/keyboard.playdate.lua
@@ -0,0 +1,373 @@
+-- keyboard component for the playdate
+-- from Orllewin
+-- https://publish.obsidian.md/orllewin/computers/playdate/Text+Input+Screen
+
+class('TextInputScreen').extends(playdate.graphics.sprite)
+
+local gfx <const> = playdate.graphics
+
+local chars = {  "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"}
+                
+local upper = {  "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"}
+                
+local xCoords = {  38, 74, 110, 146, 182, 218, 254, 290, 326, 362, 
+                  38, 74, 110, 146, 182, 218, 254, 290, 326, 362, 
+                  56, 92, 128, 164, 200, 236, 272, 308, 344, 
+                  74, 110,146, 182, 218, 254, 290}
+                  
+local yCoords = {100, 125, 150, 175}
+
+local row1CharCount = 10
+local row2CharCount = 10
+local row3CharCount = 9
+local row4CharCount = 8
+local row5CharCount = 2
+              
+local keyRow1Y = 100
+local keyRow2Y = 125
+local keyRow3Y = 150
+local keyRow4Y = 175
+
+local focusWidth = 26
+local focusHeight = 30
+
+local margin = 20
+
+function TextInputScreen:init()
+  TextInputScreen.super.init(self)
+  
+  self.lower = true
+  self.showing = false
+  self.input = ""
+  
+  self.defaultFont = gfx.getFont()
+  local pixarlmed = gfx.font.new("Fonts/pixarlmed")
+  gfx.setFont(pixarlmed)
+
+  self.backgroundImageLower = playdate.graphics.image.new(400, 240)
+  gfx.pushContext(self.backgroundImageLower)
+  playdate.graphics.setColor(playdate.graphics.kColorWhite)
+  gfx.fillRect(0, 0, 400, 240)
+  playdate.graphics.setColor(playdate.graphics.kColorBlack)
+    
+  for n=1,36 do      
+      local y = 0
+      if n <= 10 then
+        y = keyRow1Y
+      elseif n <= 20 then 
+        y = keyRow2Y
+      elseif n <= 29 then
+        y = keyRow3Y
+      else
+        y = keyRow4Y
+      end
+      
+      gfx.drawTextAligned(chars[n], xCoords[n], y, kTextAlignment.center)
+  end
+  
+  gfx.drawTextAligned("del", 343, 175, kTextAlignment.center)
+  gfx.drawTextAligned("space", 200, 205, kTextAlignment.center)
+  gfx.drawTextAligned("done", 335, 205, kTextAlignment.center)
+  
+  gfx.popContext()
+  
+  self.backgroundImageUpper = playdate.graphics.image.new(400, 240)
+  gfx.pushContext(self.backgroundImageUpper)
+  playdate.graphics.setColor(playdate.graphics.kColorWhite)
+  gfx.fillRect(0, 0, 400, 240)
+  playdate.graphics.setColor(playdate.graphics.kColorBlack)
+    
+  for n=1,36 do      
+      local y = 0
+      if n <= 10 then
+        y = keyRow1Y
+      elseif n <= 20 then 
+        y = keyRow2Y
+      elseif n <= 29 then
+        y = keyRow3Y
+      else
+        y = keyRow4Y
+      end
+      
+      gfx.drawTextAligned(upper[n], xCoords[n], y, kTextAlignment.center)
+  end
+  
+  gfx.drawTextAligned("del", 343, 175, kTextAlignment.center)
+  gfx.drawTextAligned("space", 200, 205, kTextAlignment.center)
+  gfx.drawTextAligned("done", 335, 205, kTextAlignment.center)
+  
+  gfx.popContext()
+  
+  self:setImage(self.backgroundImageLower)
+  self:moveTo(200, 120)
+  
+  self.rowIndex = 3
+  self.letterIndex = 5
+  
+  local focusImage = playdate.graphics.image.new(focusWidth, focusHeight)
+  gfx.pushContext(focusImage)
+  playdate.graphics.setColor(playdate.graphics.kColorBlack)
+  gfx.drawRoundRect(0, 0, focusWidth, focusHeight, 7)
+  gfx.popContext()
+  self.focusSprite = gfx.sprite.new(focusImage)
+  
+  local spacebarWidth = 136
+  local spacebarHeight = focusHeight
+  local spacebarImage = playdate.graphics.image.new(spacebarWidth, 30)
+  gfx.pushContext(spacebarImage)
+  playdate.graphics.setColor(playdate.graphics.kColorBlack)
+  gfx.drawRoundRect(0, 0, spacebarWidth, spacebarHeight, 7)
+  gfx.popContext()
+  self.spacebarSprite = gfx.sprite.new(spacebarImage)
+  self.spacebarSprite:moveTo(200, 216)
+  
+  local deleteWidth = 50
+  local deleteHeight = focusHeight
+  local deleteImage = playdate.graphics.image.new(deleteWidth, 30)
+  gfx.pushContext(deleteImage)
+  playdate.graphics.setColor(playdate.graphics.kColorBlack)
+  gfx.drawRoundRect(0, 0, deleteWidth, deleteHeight, 7)
+  gfx.popContext()
+  self.deleteSprite = gfx.sprite.new(deleteImage)
+  self.deleteSprite:moveTo(345, keyRow4Y + (focusHeight/2) - 5)
+  
+  local doneWidth = 63
+  local doneHeight = focusHeight
+  local doneImage = playdate.graphics.image.new(doneWidth, 30)
+  gfx.pushContext(doneImage)
+  playdate.graphics.setColor(playdate.graphics.kColorBlack)
+  gfx.drawRoundRect(0, 0, doneWidth, doneHeight, 7)
+  gfx.popContext()
+  self.doneSprite = gfx.sprite.new(doneImage)
+  self.doneSprite:moveTo(336, 216)
+  
+  
+  local inputImage = playdate.graphics.image.new(1, 1)
+
+  self.inputSprite = gfx.sprite.new(inputImage)
+  self.inputSprite:moveTo(200, 67)
+end
+
+function TextInputScreen:isShowing()
+  return self.showing
+end
+
+function TextInputScreen:push(message, onDone)
+  self.onDone = onDone
+  self:add()
+  self.focusSprite:add()
+  self.inputSprite:add()
+  
+  self:updateFocusCaret()
+  
+  if message ~= nil then
+    local messageImage = gfx.imageWithText(message, 400, 100)
+    self.messageSprite = gfx.sprite.new(messageImage)
+    self.messageSprite:moveTo(200, 25)
+    self.messageSprite:add()
+  end
+  
+  self.inputHandler = {
+    
+    cranked = function(change, acceleratedChange)
+      
+    end,
+    
+    leftButtonDown = function()
+      self.letterIndex = math.max(1, self.letterIndex  - 1)
+      self:updateFocusCaret()
+    end,
+    
+    rightButtonDown = function()
+      self.letterIndex += 1
+      
+      if self.rowIndex == 1 then
+        if self.letterIndex > row1CharCount then self.letterIndex = row1CharCount end
+       elseif self.rowIndex == 2 then
+        if self.letterIndex > row2CharCount then self.letterIndex = row2CharCount end 
+      elseif self.rowIndex == 3 then
+        if self.letterIndex > row3CharCount then self.letterIndex = row3CharCount end    
+      elseif self.rowIndex == 4 then
+        if self.letterIndex > row4CharCount then self.letterIndex = row4CharCount end      
+      end
+      self:updateFocusCaret()
+    end,
+    
+    upButtonDown = function()
+      self.rowIndex = math.max(1, self.rowIndex - 1)
+      if self.rowIndex == 4 then
+        self.letterIndex = 4
+      end
+      self:updateFocusCaret()
+    end,
+    
+    downButtonDown = function()
+      self.rowIndex = math.min(5, self.rowIndex + 1)
+      if self.rowIndex == 1 then
+        if self.letterIndex > row1CharCount then self.letterIndex = row1CharCount end
+       elseif self.rowIndex == 2 then
+        if self.letterIndex > row2CharCount then self.letterIndex = row2CharCount end 
+      elseif self.rowIndex == 3 then
+        if self.letterIndex > row3CharCount then self.letterIndex = row3CharCount end    
+      elseif self.rowIndex == 4 then
+        if self.letterIndex > row4CharCount then self.letterIndex = row4CharCount end 
+      elseif self.rowIndex == 5 then  
+        --space bar  
+        self.letterIndex = 1 
+      end
+      self:updateFocusCaret()
+      
+    end,
+    
+    BButtonDown = function()
+      self.lower = not self.lower
+      
+      if self.lower then
+        self:setImage(self.backgroundImageLower)
+      else
+        self:setImage(self.backgroundImageUpper)
+      end
+    end,
+    
+    AButtonDown = function()
+      self.focusSprite:moveBy(0, 1)
+      self.spacebarSprite:moveBy(0, 1)
+      self.deleteSprite:moveBy(0, 1)
+      
+      if self.rowIndex == 1 then
+        if self.lower then
+          self.input = self.input .. chars[self.letterIndex]
+        else
+          self.input = self.input .. upper[self.letterIndex]
+        end
+      elseif self.rowIndex == 2 then
+        if self.lower then
+          self.input = self.input .. chars[self.letterIndex + 10]
+        else
+          self.input = self.input .. upper[self.letterIndex + 10]
+        end
+      elseif self.rowIndex == 3 then
+        if self.lower then
+          self.input = self.input .. chars[self.letterIndex + 20]
+        else
+          self.input = self.input .. upper[self.letterIndex + 20]
+        end
+      elseif self.rowIndex == 4 then
+        if self.letterIndex == row4CharCount then
+          if string.len(self.input) > 0 then
+            self.input = self.input:sub(1, -2)
+          end
+        else
+          if self.lower then
+            self.input = self.input .. chars[self.letterIndex + 29]
+          else
+            self.input = self.input .. upper[self.letterIndex + 29]
+          end
+        end
+      elseif self.rowIndex == 5 then
+        if self.letterIndex == 1 then
+          self.input = self.input .. " "
+        elseif self.letterIndex == 2 then
+          self:pop()
+          return
+        end
+        
+      end
+      
+      print("Input: " .. self.input)
+      
+      if string.len(self.input) > 0 then
+        local inputImage = gfx.imageWithText(self.input, 400, 100)
+        self.inputSprite:setImage(inputImage)
+        self.inputSprite:add()
+      else
+        self.inputSprite:remove()
+      end
+    end,
+    
+    BButtonUp = function()
+      
+    end,
+    
+    AButtonUp = function()
+      self.focusSprite:moveBy(0, -1)
+      self.spacebarSprite:moveBy(0, -1)
+      self.deleteSprite:moveBy(0, -1)
+    end
+  }
+  playdate.inputHandlers.push(self.inputHandler)
+  self.showing = true
+end
+
+function TextInputScreen:updateFocusCaret()
+  if self.rowIndex == 1 then
+    self.focusSprite:moveTo(xCoords[self.letterIndex], yCoords[self.rowIndex] + (focusHeight/2) - 5)
+    self.focusSprite:add()
+    self.spacebarSprite:remove()
+    self.deleteSprite:remove()
+  elseif self.rowIndex == 2 then
+    self.focusSprite:moveTo(xCoords[self.letterIndex + 10], yCoords[self.rowIndex] + (focusHeight/2) - 5)
+    self.focusSprite:add()
+    self.spacebarSprite:remove()
+    self.deleteSprite:remove()
+  elseif self.rowIndex == 3 then
+    self.focusSprite:moveTo(xCoords[self.letterIndex + 20], yCoords[self.rowIndex] + (focusHeight/2) - 5)
+    self.focusSprite:add()
+    self.spacebarSprite:remove()
+    self.deleteSprite:remove()
+  elseif self.rowIndex == 4 then
+    if self.letterIndex == row4CharCount then
+      --delete
+      self.focusSprite:remove()
+      self.spacebarSprite:remove()
+      self.deleteSprite:add()
+    else
+      self.focusSprite:moveTo(xCoords[self.letterIndex + 29], yCoords[self.rowIndex] + (focusHeight/2) - 5)
+      self.focusSprite:add()
+      self.spacebarSprite:remove()
+      self.deleteSprite:remove()
+    end
+    self.doneSprite:remove()
+  elseif self.rowIndex == 5 then
+    self.focusSprite:remove()
+    self.deleteSprite:remove()
+    if self.letterIndex == 1 then
+      self.spacebarSprite:add()
+      self.doneSprite:remove()
+    elseif self.letterIndex == 2 then
+      self.spacebarSprite:remove()
+      self.doneSprite:add()
+    end
+  else
+    print("Invalid row index: " .. self.rowIndex)
+  end
+end
+
+function TextInputScreen:pop()
+  self.isShowing = false
+  gfx.setFont(self.defaultFont)
+  self.focusSprite:remove()
+  self.spacebarSprite:remove()
+  self.deleteSprite:remove()
+  self.doneSprite:remove()
+  self.inputSprite:remove()
+  self.focusSprite = nil
+  self.spacebarSprite = nil
+  self.deleteSprite = nil
+  self.doneSprite = nil
+  self.inputSprite = nil
+  if self.messageSprite ~= nil then 
+    self.messageSprite:remove() 
+    self.messageSprite = nil
+  end
+  self:remove()
+  
+  playdate.inputHandlers.pop()
+  if self.onDone ~= nil then self.onDone(self.input) end
+end
\ No newline at end of file