1 /************************************************************************
2  * This file is part of Wizznic.                                        *
3  * Copyright 2009-2015 Jimmy Christensen <dusted@dusted.dk>             *
4  * Wizznic is free software: you can redistribute it and/or modify      *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation, either version 3 of the License, or    *
7  * (at your option) any later version.                                  *
8  *                                                                      *
9  * Wizznic is distributed in the hope that it will be useful,           *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
12  * GNU General Public License for more details.                         *
13  *                                                                      *
14  * You should have received a copy of the GNU General Public License    *
15  * along with Wizznic.  If not, see <http://www.gnu.org/licenses/>.     *
16  ************************************************************************/
17 
18 #include "strinput.h"
19 #include "input.h"
20 #include "strings.h"
21 
22 static char kbl[4][10] = {
23   {'1','2','3','4','5','6','7','8','9','0'},
24   {'q','w','e','r','t','y','u','i','o','p'},
25   {'a','s','d','f','g','h','j','k','l',';'},
26   {'z','x','c','v','b','n','m',' ',',','.'}
27 };
28 
29 static char kbh[4][10] = {
30   {'!','"','#','$','%','&','/','(',')','='},
31   {'Q','W','E','R','T','Y','U','I','O','P'},
32   {'A','S','D','F','G','H','J','K','L',':'},
33   {'Z','X','C','V','B','N','M','_',',','.'}
34 };
35 
36 static int kbRows = 4;
37 static int kbCols = 10;
38 
39 
40 
41 
42 //Return a state structure for use with inpGetStr and inpGetStrClear
inpStrCreate(SDL_Surface * dstSurface,char * promptTxt,size_t minLen,size_t maxLen)43 inpStrState* inpStrCreate(SDL_Surface* dstSurface, char* promptTxt, size_t minLen, size_t maxLen )
44 {
45   inpStrState* s = malloc( sizeof(inpStrState) );
46   s->dstSurface=dstSurface;
47   s->maxLen=maxLen;
48   s->minLen=minLen;
49   s->prompt=promptTxt;
50 
51   s->str=malloc(sizeof(char)*(maxLen+1));
52   s->_buf=malloc( (sizeof(char))*(maxLen+strlen(s->prompt)+2) );
53 
54   inpStrClear(s);
55   return(s);
56 }
57 
inpStrClear(inpStrState * state)58 void inpStrClear(inpStrState* state)
59 {
60   memset(state->str, 0, (state->maxLen+1) );
61   state->curX=0;
62   state->curY=0;
63   state->curPos=0;
64   state->kb=&kbl;
65 }
66 
67 //Return 0 until a string is present in state->str.
inpStrGet(inpStrState * state,int menuPosX,int menuPosY,int blink)68 int inpStrGet(inpStrState* state, int menuPosX, int menuPosY, int blink)
69 {
70   int cy,cx;
71   char hack[2]={ ' ',0x00 };
72   int hsKeyboardWasClicked=0;
73 
74   txtWriteCenter(state->dstSurface, FONTSMALL, STR_STRINPUT_CONTROLS, HSCREENW,HSCREENH+108);
75 
76   if( getChar() )
77   {
78     if( getChar() == SDLK_RETURN )
79     {
80       //Save
81       menuPosY=4;
82       hsKeyboardWasClicked=1;
83     }
84 
85     if( getChar() == SDLK_BACKSPACE && strlen( state->str ) > 0 )
86     {
87       state->str[ strlen(state->str)-1 ]=0;
88     } else if( getChar() > 31 && getChar() < 123 && strlen( state->str ) < state->maxLen+1 )
89     {
90       state->str[ strlen(state->str) ] = getChar();
91       state->str[ strlen(state->str)+1 ] = 0x0;
92     }
93   }
94 
95   sprintf(state->_buf, "%s %s", state->prompt, state->str);
96 
97   txtWrite(state->dstSurface, FONTSMALL, state->_buf, HSCREENW-110, HSCREENH-45);
98 
99 
100   for(cy=0; cy < kbRows; cy++)
101   {
102     for(cx=0; cx < kbCols; cx++)
103     {
104 
105       if( (menuPosX==cx && menuPosY==cy) && !blink && !( getInpPointerState()->timeSinceMoved < POINTER_SHOW_TIMEOUT  ) )
106       {
107         txtWrite(state->dstSurface, FONTSMALL, "[_]", (HSCREENW-70)+(cx)*16-8, (HSCREENH-9)+cy*15);
108       }
109 
110       hack[0]=(*(state->kb))[cy][cx];
111       txtWrite(state->dstSurface, FONTSMALL, hack, (HSCREENW-70)+cx*16, (HSCREENH-10)+cy*15);
112       hack[0]=0;
113       if( isBoxClicked( getTxtBox() ) )
114       {
115         menuPosX=cx;
116         menuPosY=cy;
117         hsKeyboardWasClicked=1;
118       }
119     }
120   }
121 
122   //Only show "ENTER" if string nonempty
123   if( strlen(state->str) )
124   {
125     //Blink "ENTER" underline if selected
126     if( menuPosY==4 && blink)
127     {
128       if(menuPosX > 9) menuPosX=0;
129       txtWriteCenter(state->dstSurface, FONTSMALL, " _____ ", HSCREENW, HSCREENH+50);
130     }
131     txtWriteCenter(state->dstSurface, FONTSMALL, "[ENTER]", HSCREENW, HSCREENH+50);
132     if( isBoxClicked( getTxtBox() ) )
133     {
134       menuPosY=4;
135       hsKeyboardWasClicked=1;
136     }
137   }
138 
139   //Blink "Caps" underline if selected
140   if( menuPosX==10 && blink)
141   {
142     if(menuPosY >3) menuPosY =1;
143     txtWrite( state->dstSurface, FONTSMALL, " ____", HSCREENW-130, HSCREENH+10 );
144   }
145   txtWrite( state->dstSurface, FONTSMALL, "[Caps]", HSCREENW-130, HSCREENH+10 );
146   if( isBoxClicked( getTxtBox() ))
147   {
148     menuPosX=10;
149     hsKeyboardWasClicked=1;
150   }
151 
152   //If the cursor is being used, show "delete" button, this is only usable with pointer.
153   if(  getInpPointerState()->timeSinceMoved < POINTER_SHOW_TIMEOUT  )
154   {
155     txtWrite(state->dstSurface, FONTSMALL, "[DEL]", (HSCREENW+38), (HSCREENH-25) );
156     if( isBoxClicked( getTxtBox() ))
157     {
158       menuPosY=5;
159       hsKeyboardWasClicked=1;
160     }
161   }
162 
163   //Switch layouts if we're at posX 10
164   if( menuPosX == 10 && (getButton( C_BTNB ) || hsKeyboardWasClicked) )
165   {
166 
167     resetBtn( C_BTNB );
168     if(state->kb==&kbl)
169     {
170       state->kb=&kbh;
171     } else if(state->kb==&kbh) {
172       state->kb=&kbl;
173     }
174 
175   } else if( menuPosY==4 && ( getButton( C_BTNB ) || hsKeyboardWasClicked ) ) //Return true
176   {
177     resetBtn( C_BTNB );
178     if(strlen( state->str ) >= state->minLen)
179     {
180       return(1);
181     }
182   } else if( getButton( C_BTNB ) || (hsKeyboardWasClicked && menuPosY < 5) )
183   {
184     resetBtn( C_BTNB );
185     resetMouseBtn();
186     if( strlen( state->str ) < state->maxLen+1)
187     {
188       state->str[ strlen(state->str) ] = (*(state->kb))[menuPosY][menuPosX];
189       state->str[ strlen(state->str)+1 ] = 0;
190     }
191   } else if( getButton( C_BTNA ) || (hsKeyboardWasClicked && menuPosY == 5) )
192   {
193     resetBtn( C_BTNA);
194     if(strlen(state->str) > 0)
195     {
196       state->str[ strlen(state->str)-1 ]=0;
197     }
198   }
199   return(0);
200 }
201