onscreen keyboard

Previous topic - Next topic

Yommy

well i am trying to make an onscreen keyboard that i can use in future projects


Code (glbasic) Select

// --------------------------------- //
// Project: gp2x testing
// Start: Saturday, July 12, 2008
// IDE Version: 5.322
SETTRANSPARENCY RGB(255,0,255)
LOADSPRITE "keyboard.bmp", 0
LOADFONT "smalfont.bmp", 0
SYSTEMPOINTER TRUE
DIM key3$[6][13]
//first row
LET key3$[1][1]="1"
LET key3$[1][2]="2"
LET key3$[1][3]="3"
LET key3$[1][4]="4"
LET key3$[1][5]="5"
LET key3$[1][6]="6"
LET key3$[1][7]="7"
LET key3$[1][8]="8"
LET key3$[1][9]="9"
LET key3$[1][10]="0"
LET key3$[1][11]="-"
LET key3$[1][12]="="
//second row
LET key3$[2][1]="q"
LET key3$[2][2]="w"
LET key3$[2][3]="e"
LET key3$[2][4]="r"
LET key3$[2][5]="t"
LET key3$[2][6]="y"
LET key3$[2][7]="u"
LET key3$[2][8]="i"
LET key3$[2][9]="o"
LET key3$[2][10]="p"
//LET key3$[2][11]="BACKSPACE"
//LET key3$[2][12]="BACKSPACE"
//third row
LET key3$[3][1]="CAPS"
LET key3$[3][2]="a"
LET key3$[3][3]="s"
LET key3$[3][4]="d"
LET key3$[3][5]="f"
LET key3$[3][6]="g"
LET key3$[3][7]="h"
LET key3$[3][8]="j"
LET key3$[3][9]="k"
LET key3$[3][10]="l"
LET key3$[3][11]="ENTER"
LET key3$[3][12]="ENTER"
//forth row
LET key3$[4][1]="SHIFT"
LET key3$[4][2]="z"
LET key3$[4][3]="x"
LET key3$[4][4]="c"
LET key3$[4][5]="v"
LET key3$[4][6]="b"
LET key3$[4][7]="n"
LET key3$[4][8]="m"
LET key3$[4][9]=","
LET key3$[4][10]="."
LET key3$[4][11]="/"
//fifth row
LET key3$[5][2]=";"
LET key3$[5][3]="`"
LET key3$[5][4]="'"
LET key3$[5][5]=" "
LET key3$[5][6]=" "
LET key3$[5][7]=" "
LET key3$[5][8]=" "
LET key3$[5][9]=" "
LET key3$[5][10]="["
LET key3$[5][11]="]"
LET key3$[5][12]="\\ "

LET GLOBAL text$="text:"

WHILE KEY(28)=FALSE
DRAWSPRITE 0,63,159
MOUSESTATE mx, my, b1, b2
IF b1
IF mousefree THEN keyboardclick(mx,my)
mousefree=FALSE
ELSE
mousefree=TRUE
    ENDIF
    PRINT text$,0,0
SHOWSCREEN
WEND



// ------------------------------------------------------------- //
// ---  KEYBOARDCLICK  ---
// ------------------------------------------------------------- //
FUNCTION keyboardclick: row, key2
LET row=INTEGER(my/16-9)
IF row=1 OR row=3 OR row=5
LET key2 = INTEGER(mx/16-3)
ELSEIF row=2 OR row=4
LET key2 = INTEGER((mx+8)/16-4)
ENDIF
IF key2<1 OR key2>12 OR row<1 OR row>5
row=0
key2=0
ENDIF
IF row=2 AND (key2=11 OR key2=12)
text$=MID$(text$,0,(LEN(text$)-1))
ELSE
text$=text$+key3$[row][key2]
ENDIF
ENDFUNCTION // KEYBOARDCLICK


a few questions
how could i make this cleaner?
what would be the best way for the return key?
also im getting a lot of warnings about variables:
"gp2x testing.gbas"(78) warning : probably unassigned variable : b2
"gp2x testing.gbas"(9) warning : implicitly created GLOBAL  : key3$

thank you
Yommy

Kitty Hello

Well, instead of using a 2D array, you could use a 1D array for each row, then the horizontal characters in a string like:

DIMDATA lines$[], "1234567890-=", "qwertyuiop\b"...
you can use the x-coordinate with mid$ then.

However, you have a few special "characters", like shift and caps-lock, whic would require special characters then (like: chr$(1) or so...)

Instread of a GLOBAL text$, you could pass that variable with a "BYREF" modifier, so you can change it from within the function.

FUNCTION GetText: BYREF t$
   t$ = "changed"
ENDFUNCTION


Yommy



Code (glbasic) Select

// --------------------------------- //
// Project: gp2x Keyboard            //
// Start: Saturday, July 12, 2008    //
// IDE Version: 5.322                //
// --------------------------------- //
LOCAL text$
Kinit()
KShow(text$)
PRINT text$,20,20
SHOWSCREEN
KEYWAIT

// ------------------------------------------------------------- //
// ---  KCLICK  ---
// ------------------------------------------------------------- //
FUNCTION Kclick: mx, my, BYREF t$
       LOCAL row, key2
       GLOBAL lchars$[], uchars$[]
       LET row=INTEGER((my-13)/25)-5
       LET key2=INTEGER((mx-16)/24)-1
       IF key2<0 OR key2>10 OR row<0 OR row>4 THEN RETURN
       IF row=2 AND (key2=8 OR key2=9) // delete key
              t$ = MID$(t$,0,(LEN(t$)-1))
       ELSE
              t$ = t$+(MID$(lchars$[row],key2,1))
       ENDIF
ENDFUNCTION // KCLICK


// ------------------------------------------------------------- //
// ---  KSHOW  ---
// ------------------------------------------------------------- //
FUNCTION KShow: BYREF t$
//WHILE KeyboardEnabled = TRUE
WHILE TRUE //debug loop
       LOCAL mx, my, b1, b2
       DRAWSPRITE 0,39,138
       MOUSESTATE mx, my, b1, b2
       IF b1 THEN Kclick(mx,my,t$)
       PRINT t$,0,0
       SHOWSCREEN
       MOUSEWAIT
WEND
ENDFUNCTION // KSHOW


// ------------------------------------------------------------- //
// ---  KINIT  ---
// ------------------------------------------------------------- //
FUNCTION Kinit:
       SETTRANSPARENCY RGB(255,0,255)
       LOADSPRITE "lcase.bmp", 0
       LOADSPRITE "ucase.bmp", 1
       LOADSPRITE "symbol.bmp", 2
       LOADFONT "smalfont.bmp", 0
       SYSTEMPOINTER TRUE
       DIMDATA lchars$[],"qwertyuiop","asdfghjkl'","#zxcvbnm##","##      ##"
       DIMDATA uchars$[],"QWERTYUIOP","ASDFGHJKL'","#ZXCVBNM##","##      ##"
ENDFUNCTION // KINIT


im trying to make it so i can easily add this without much code hacks.
i think this is going to fail at showing something in the background behind the keyboard, while the keyboard is in use :(
any way i can avoid this.

Thank you for your help Gernot, it really cleaned up nice <3
Yommy

Kitty Hello

Oh boy!!! This is so cool!
Now one tiny tiny change:
Instead of the bitmaps, use polyvector and print, so you don't need resources. :D

The function KShow should _not_ do a SHOWSCREEN, MOUSEWAIT.
This way you can do this:

Code (glbasic) Select

Kinit()
WHILE game_on
  DrawMyGame()
  enter_was_pressed = KShow()
  SHOWSCREEN
  if enter_was_pressed then END
WEND


In Kshow, you must remember if the mouse was down last time (STATIC mouse_was_down) and if the mouse is released, then do a Kclick(). Keep this work up. It's amazing and it looks really good. 

Yommy

#4
ohh now i see, not only do i not have the game in the background, im also stopping the game while the keyboard is active, thanks
i will also give this polyvector thingo a try , i saw your post about round oblong shapes :)
Would drawing the keyboard be more cpu intensive, since this is aimed at devices with no keyboard, ie not 10ghz pc's

Yommy

Kitty Hello

Well, it *might* be a small slowdown. Must not neccessarily.
I suggest a much better idea: CALLBACK!

Code (glbasic) Select

CALLBACK FUNCTION KDrawKey: text$, x,y,width,height,is_pushed
LOCAL fx,fy
   GETFONTSIZE fx, fy
   // shadow
   DRAWRECT x+1,y+1,width-2,height-2,RGB(0x20,0x20,0x20)
   DEC width, 4
   DEC height, 4
   INC x,2
   INC y,2
   IF is_pushed
      DRAWRECT x,y,width,height,RGB(0x80,0x80,0x80)
   ELSE
      DRAWRECT x,y,width, height,RGB(0xc0,0xc0,0xc0)
   ENDIF

   // Center the text
   ALPHAMODE -.7
   PRINT text$, x+(width-LEN(text$)*fx)/2, y+(height-fy)/2
ENDFUNCTION


This way you can "overwrite" this function in your game as you need it, and others can, too.
The default (CALLBACK) function should run w/o and SPRITE command, though. My example above is quite something.

Yommy

although a code drawn keyboard wont use resources, i still like the sprite way
its simpler to edit the resource, less code, keyboard can look nicer as an image (gradient etc),
getting the same image result from code would be a waste of resources.

or am i wrong, i dont know, i have only been coding a few days
i dont see any other advantage other than it using no resources

Yommy

Yommy

so, the whole draw the keyboard idea went perfect.....until i got the scaling text onto the keys
ROTOZOOMANIM with 36x32 arial font

kinda works, but kinda bleh
also the other idea was multiple font files, but then i may aswell just use keyboard images
anybody have any more ideas to achieve a nice scalable text

Yommy

Kitty Hello

Try SMOOTHSHADING TRUE before ROTOZOOMANIM, and make the font even bigger, maybe?

Yommy

SMOOTHSHADING is default to true, setting this to false has a bad effect too :(

Kitty Hello

Very bad.
What if you make a mush larger font for that? 48x48?

Thanks for your idea, I played a bit with DDgui (get it in the next update).

Kitty Hello

Ha! Try using ALPHAMODE -0.99 before you draw. That could improve things massively. However, not on GP2X. Here a different font file is required urgently.

matchy

Cool keyboard....well done!!

Billamu

The word 'gp2x-f200' comes to mind...  =D
I'm an Aries. I have lots of Ram.

Hemlos

#14
dont use clear-type or antialias type, you might get better visual results with the standard font.
Also try starting with a smaller font and scale up instead of down.
Bing ChatGpt is pretty smart :O