Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Keyboard

edited December 2011 in Code Sharing Posts: 447

http://ruilov.posterous.com/keyboard-v1

Edit: v3 here http://ruilov.posterous.com/keyboard-v3

I took snapshots of the keyboard on the IPad, converted to grayscale and did some encoding to reduce the file sizes, and saved as project data.

Will add more textbox functionality next, like resetting the text and being able to place the cursor in the middle of the text.

Comments

  • Posts: 2,820

    Cool. I'll try to try it when I get to my iPad.

  • Posts: 14

    Could u plz use pastebin.com for sharing codes?:D-i have problems with this website

  • Posts: 273

    @Sajjad. Try going to posterous.com using mobile Safari on your iPad instead of Codea's own built-in browser. If you then click and hold on the file you should be able to open it in Codea...

  • Posts: 447

    @Sajjad, what's the problem with it? Works well for me

  • BortelsBortels Mod
    Posts: 1,557

    @ruilov - you're a genius! It never occurred to me to take a shot of the regular keyboard - this looks awesome, and works very well. You even have keyclick! A+, 10 poins to @ruilov!

    The only caveat is its really big - but until we get jpg/png/gif/spritepack-upload, you can't avoid that...

  • edited December 2011 Posts: 447

    @Bortels, I pushed myself to make the file smaller because I knew you'd say that :)

    I have no issue with being big, it's 1.2 megs, the storage of old floppys. The issue I have is with it being slow. Can't think of how to avoid slowness in the current release though.

  • BortelsBortels Mod
    Posts: 1,557

    heh, yeah, I almost didn't comment on the size because I saw you worked on encoding it to make it smaller. I'm old - the part of my brain that looks at data when I'm coding still lives in an 8-bit 90k floppy disk 300 baud modem world...

  • Posts: 1,255

    That's terrific, just very impressive on every point.

    Hmmm. The keyboard normally displayed on a portrait screen would be darn near perfect fora standard displaymode setup.

  • Posts: 447

    Ah good idea. I should be able to get that added too, but first maybe I'll just see what happens if I display the sprite with smaller width,height

  • edited December 2011 Posts: 447

    Here's v2: http://ruilov.posterous.com/keyboard-v2

    More textbox functionality. Crop text to fit in the box. Allow placing the cursor in the middle of the text. Reset button.

  • Posts: 447

    @Mark, added a standard mode. The scaled down sprites don't look that great but I think will do. Keyboard.setDisplayMode(STANDARD) to turn it on.

    http://ruilov.posterous.com/keyboard-v3

  • Genius! Wow! Amazing!

  • Posts: 20

    Nice work.

    Does anyone else get a crash when opening up the function list in the Codea editor and scrolling down a bit in the list of functions? This is with the v2 code.

  • BortelsBortels Mod
    Posts: 1,557

    I had it do that once! Re-ran codea and it was fine. Maybe some really-big-project bug? (Yes, 1.3 megs isn't "big" - but for a Codea project, it's huge... I doubt they tested too much with giant blobs of image data...)

  • edited December 2011 Posts: 447

    @Eric I get a crash too. @Twolivesleft, is there somewhere where you'd like us to post bug reports?

    This is with ipad2 on the latest os (5.1 or something like that) on either v2 or v3 of the keyboard code

  • Posts: 384

    This is so cool. I can't wait to see where it leads us.

  • SimeonSimeon Admin Mod
    Posts: 5,363

    @ruilov your keyboard is absolutely amazing! The function browser crash is actually fixed in Codea 1.2.6, which is still waiting for approval (also has reorderable tabs so you don't have to use alphabetical class names).

    Also, just note you can read the current displayMode by calling displayMode() without any arguments. So you can set your keyboard's display mode automatically if you like. That is:

    if displayMode() == STANDARD then
        -- show keyboard in standard mode
    else
        -- show keyboard in fullscreen
    end
    

    You can report issues here in the future though: https://bitbucket.org/TwoLivesLeft/codea/issues

  • Posts: 447

    @Simon, I didn't know you could read the displayMode, thanks!

  • Posts: 447

    speaking of cursor control, here's a new version of the keyboard code. Now that we have native support for keyboard and text (remember when we didn't?) all that this code needs to do is handle the cursor and display of text.

    Unfortunately it doesn't handle left/right keys (from a bluetooth keyboard) as those keys don't trigger a keyboard(key) call

    function setup()
        textboxes = {Textbox(10,HEIGHT - 100,250),Textbox(10,HEIGHT - 200,WIDTH - 100)}
        textboxes[2]:setFontSize(50)
        textboxes[2].fontProperties.fill = color(255, 0, 0, 255)
        textboxes[2].borderColor = color(14, 255, 0, 255)
    end
    
    function draw()
        background(0, 0, 0)
        for _,textbox in ipairs(textboxes) do textbox:draw() end
    end
    
    function touched(touch)
        for _,textbox in ipairs(textboxes) do textbox:touched(touch) end
    end
    
    function keyboard(key)
        for _,textbox in ipairs(textboxes) do textbox:keyboard(key) end
    end
    
  • Posts: 447

    Textbox = class() function Textbox:init(x,y,w) self.text = "" self.x = x self.y = y self.width = w -- in font properties you can set fill,font,fontSize self.fontProperties = {font="AmericanTypewriter-Bold",fill=color(255,255,255)} self:setFontSize(30) self.borderColor = color(255, 255, 255, 255) -- internal state self.active = false self.cursorPos = 0 -- 0 means before the first letter, 1 after the first, so on self.startPos = 1 -- the first char we show on the box (index into self.text) end function Textbox:setFontSize(x) self.fontProperties.fontSize = x -- calculate the height based on font properties pushStyle() self:applyTextProperties() local w,h = textSize("dummy") popStyle() self.height = h end -- call back for when a key is pressed function Textbox:keyboard(key) -- if not active, ignore if not self.active then return nil end if key == BACKSPACE then -- if we press backspace. Note if we're already at the start, nothing to do if self.cursorPos > 0 then local prefix = self.text:sub(1,self.cursorPos-1) local posfix = self.text:sub(self.cursorPos+1,self.text:len()) self.text = prefix..posfix self.cursorPos = self.cursorPos - 1 -- need to improve this behavior for when the cursor is at the -- start of what's showing. We should go back as much as we can instead of 1 if self.cursorPos < self.startPos then local width = self:maxTextWidth() self.startPos = 1 self:moveCursor(self.cursorPos) end end else local prefix = self.text:sub(1,self.cursorPos) local posfix = self.text:sub(self.cursorPos+1,self.text:len()) self.text = prefix..key..posfix self:moveCursor(self.cursorPos + key:len()) end end function Textbox:applyTextProperties() textMode(CORNER) font(self.fontProperties.font) fontSize(self.fontProperties.fontSize) fill(self.fontProperties.fill) end -- when the text box is active, the keyboard shows up (and coursor and other elements too) function Textbox:activate() self.active = true -- move the cursor to the end self:moveCursor(self.text:len()) showKeyboard() end function Textbox:inactivate() self.active = false self.startPos = 1 hideKeyboard() end -- newPos is specified in chars, not pixels function Textbox:moveCursor(newPos) self.cursorPos = newPos local width = self:maxTextWidth() local cursorText = self.text:sub(self.startPos,self.cursorPos) pushStyle() self:applyTextProperties() local cursorLength = textSize(cursorText) while cursorLength > width do self.startPos = self.startPos + 1 cursorText = self.text:sub(self.startPos,self.cursorPos) cursorLength = textSize(cursorText) end popStyle() end -- how much space the text can occupy. Can be less than width if we're showing the reset button function Textbox:maxTextWidth() local width = self.width if self.active then local resetDiam,resetX,resetY = self:resetButtonCoords() width = resetX - self.x - 5 end return width end -- return coords and dimensions for the reset button function Textbox:resetButtonCoords() local resetDiam = self.height-4 local resetX = self.x+self.width-resetDiam-2 local resetY = self.y+2 return resetDiam,resetX,resetY end -- the text that we actually display, cropped up if needed function Textbox:displayText() local dispText = self.text:sub(self.startPos) pushStyle() self:applyTextProperties() local width = self:maxTextWidth() while textSize(dispText) > width do dispText = dispText:sub(1,dispText:len()-1) end popStyle() return dispText end function Textbox:draw() pushStyle() noSmooth() -- draw the box stroke(self.borderColor) strokeWidth(1) noFill() rectMode(CORNER) rect(self.x,self.y,self.width,self.height) -- draw the text self:applyTextProperties() local dispText = self:displayText() text(dispText,self.x + 5,self.y) if not self.active then popStyle() return nil end -- draw the cursor if math.floor(ElapsedTime*3)%2 == 0 then stroke(151, 167, 165, 255) strokeWidth(1) local prefix = dispText:sub(1,self.cursorPos - self.startPos + 1) local len = textSize(prefix) + 5 line(self.x+len,self.y+4,self.x+len,self.y+self.height-4) end -- draw the reset button stroke(self.borderColor) strokeWidth(1) noFill() rectMode(CORNER) ellipseMode(CORNER) local resetDiam,resetX,resetY = self:resetButtonCoords() local sq2 = (math.sqrt(2)-1)/2*1.1 ellipse(resetX,resetY,resetDiam) line(resetX+resetDiam*sq2,resetY+resetDiam*sq2, resetX+resetDiam*(1-sq2),resetY+resetDiam*(1-sq2)) line(resetX+resetDiam*sq2,resetY+resetDiam*(1-sq2), resetX+resetDiam*(1-sq2),resetY+resetDiam*sq2) popStyle() end function Textbox:touched(touch) -- check if it was the reset button that was pressed local resetDiam,resetX,resetY = self:resetButtonCoords() if touch.x>=resetX and touch.x<=self.x+self.width and touch.y>=self.y and touch.y<=self.y+self.height then if self.active and touch.state==ENDED then -- the user touched the reset button self.text = "" self.cursorPos = 0 self.startPos = 1 end end if touch.x>=self.x and touch.x<=self.x+self.width and touch.y>=self.y and touch.y<=self.y+self.height then if not self.active and touch.state == ENDED then self:activate() elseif self.active then -- place the cursor at the touch x coord local dispText = self:displayText() self.cursorPos = self.startPos-1 local touchX = touch.x - self.x pushStyle() self:applyTextProperties() for idx = 1,dispText:len() do local len = textSize(dispText:sub(1,idx)) if len > touchX then break end self.cursorPos = self.cursorPos + 1 end popStyle() end elseif touch.state == BEGAN and self.active then -- BEGAN above is important as it makes sure a box is inactivated, and hides -- the keyboard, before another box is activated at ENDED, which will show -- the keyboard again. If the other was inverted, then you'd showkeyboard only -- to hide it right after self:inactivate() end end
  • Posts: 2,820

    Nice update!

  • Posts: 122

    Very Sweet, @ruilov. I did something similar when it came to my Window Manager. Keep up the awesome work!

Sign In or Register to comment.