OGETA.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. // Filename : OGETA.CPP
  21. // Description : simple get field
  22. #include <OGETA.h>
  23. #include <OVGA.h>
  24. #include <OFONT.h>
  25. #include <OMOUSE.h>
  26. #include <KEY.h>
  27. #include <OSYS.h>
  28. #include <COLCODE.h>
  29. GetA::GetA()
  30. {
  31. input_field = NULL;
  32. field_len = 0;
  33. font_ptr = NULL;
  34. align_flag = 0;
  35. enable_flag = 1;
  36. mouse_drag_flag = 0;
  37. back_ground_bitmap = NULL;
  38. }
  39. void GetA::init( int x1, int y1, int x2, char *field, unsigned length,
  40. Font *fontPtr, char align, char detectEsc)
  41. {
  42. x = x1;
  43. y = y1;
  44. x_limit = x2;
  45. input_field = field;
  46. field_len = length;
  47. font_ptr = fontPtr;
  48. align_flag = align;
  49. enable_flag = 1;
  50. esc_key_flag = detectEsc;
  51. mouse_drag_flag = 0;
  52. back_ground_bitmap = NULL;
  53. select_whole();
  54. }
  55. int GetA::height()
  56. {
  57. return font_ptr->max_font_height;
  58. }
  59. void GetA::clear()
  60. {
  61. input_field[0] = '\0';
  62. cursor_pos = 0;
  63. clear_select();
  64. }
  65. // return 0 for no input
  66. // return key code pressed such as KEY_RETURN, KEY_ESCAPE ...
  67. unsigned GetA::detect_key()
  68. {
  69. if( !enable_flag )
  70. return 0;
  71. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  72. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  73. if( mouse.is_key_event() )
  74. {
  75. unsigned keyCode = mouse.key_code;
  76. unsigned shiftPressed = mouse.event_skey_state & SHIFT_KEY_MASK;
  77. // printable character
  78. if( keyCode >= ' ' && keyCode <= 0xff )
  79. {
  80. if( strlen(input_field)-(mark_end() - mark_begin()) < field_len)
  81. {
  82. // insert character
  83. memmove( input_field+mark_begin()+1, input_field+mark_end(),
  84. strlen(input_field)-mark_end()+1);
  85. input_field[mark_begin()] = keyCode;
  86. cursor_pos = mark_begin()+1;
  87. clear_select();
  88. }
  89. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  90. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  91. return keyCode;
  92. }
  93. else if( keyCode == KEY_DEL )
  94. {
  95. if( is_select() )
  96. {
  97. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  98. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  99. // erase selected area
  100. memmove( input_field+mark_begin(), input_field+mark_end(),
  101. strlen(input_field)-mark_end()+1);
  102. cursor_pos = mark_begin();
  103. clear_select();
  104. }
  105. else
  106. {
  107. if(strlen(input_field) > cursor_pos)
  108. {
  109. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  110. memmove( input_field+cursor_pos, input_field+cursor_pos+1,
  111. strlen(input_field)-cursor_pos);
  112. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  113. }
  114. }
  115. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  116. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  117. return keyCode;
  118. }
  119. else if( keyCode == KEY_BACK_SPACE )
  120. {
  121. if( is_select() )
  122. {
  123. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  124. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  125. // erase selected area
  126. memmove( input_field+mark_begin(), input_field+mark_end(),
  127. strlen(input_field)-mark_end()+1);
  128. cursor_pos = mark_begin();
  129. clear_select();
  130. }
  131. else
  132. {
  133. if(cursor_pos > 0)
  134. {
  135. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  136. memmove( input_field+cursor_pos-1, input_field+cursor_pos,
  137. strlen(input_field)-cursor_pos+1);
  138. cursor_pos--;
  139. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  140. clear_select();
  141. }
  142. }
  143. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  144. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  145. return keyCode;
  146. }
  147. if( keyCode == KEY_LEFT )
  148. {
  149. if(cursor_pos > 0)
  150. cursor_pos--;
  151. if( !shiftPressed )
  152. clear_select();
  153. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  154. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  155. return keyCode;
  156. }
  157. if( keyCode == KEY_RIGHT )
  158. {
  159. if(cursor_pos < strlen(input_field))
  160. cursor_pos++;
  161. if( !shiftPressed )
  162. clear_select();
  163. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  164. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  165. return keyCode;
  166. }
  167. if( keyCode == KEY_HOME)
  168. {
  169. cursor_pos = 0;
  170. if( !shiftPressed )
  171. clear_select();
  172. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  173. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  174. return keyCode;
  175. }
  176. if( keyCode == KEY_END)
  177. {
  178. cursor_pos = strlen(input_field);
  179. if( !shiftPressed )
  180. clear_select();
  181. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  182. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  183. return keyCode;
  184. }
  185. if( esc_key_flag && keyCode == KEY_ESC )
  186. {
  187. // if esc_key_flag is 0 and ESC key pressed, still return 0
  188. clear();
  189. return keyCode;
  190. }
  191. if( keyCode == KEY_RETURN || keyCode == KEY_UP ||
  192. keyCode == KEY_DOWN || keyCode == KEY_TAB )
  193. {
  194. return keyCode;
  195. }
  196. }
  197. return 0;
  198. }
  199. void GetA::paint(int paintCursor)
  200. {
  201. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) );
  202. err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) );
  203. int cursorX = font_ptr->text_width(input_field, cursor_pos);
  204. int leftX = font_ptr->text_width(input_field, mark_begin());
  205. int rightX = font_ptr->text_width(input_field, mark_end());
  206. // create a temp buffer to store character
  207. int rightLimit = x_limit - x;
  208. int textWidth = font_ptr->text_width(input_field, -1, rightLimit ) + 1;
  209. int textHeight = font_ptr->max_font_height;
  210. char *bitmap = sys.common_data_buf;
  211. err_when( 2*sizeof(short) + textWidth * textHeight > COMMON_DATA_BUF_SIZE );
  212. *(short *)bitmap = textWidth;
  213. bitmap += sizeof(short);
  214. *(short *)bitmap = textHeight;
  215. bitmap += sizeof(short);
  216. memset( bitmap, TRANSPARENT_CODE, textWidth * textHeight );
  217. if( back_ground_bitmap && !Vga::use_back_buf )
  218. {
  219. short backGroundWidth = *(short *)back_ground_bitmap;
  220. short backGroundHeight = *(1+(short *)back_ground_bitmap);
  221. // fill backGround
  222. switch(align_flag)
  223. {
  224. case 0:
  225. IMGbltArea(bitmap, textWidth, 0, 0, back_ground_bitmap,
  226. 0, 0, min(textWidth, backGroundWidth)-1, min(textHeight, backGroundHeight)-1 );
  227. break;
  228. case 1:
  229. {
  230. int l = (x_limit - x + 1 - textWidth ) / 2;
  231. if( l >= 0 && l < backGroundWidth )
  232. IMGbltArea(bitmap, textWidth, 0, 0, back_ground_bitmap,
  233. l, 0, min(l+textWidth, backGroundWidth)-1, min(textHeight, backGroundHeight)-1 );
  234. }
  235. break;
  236. case -1:
  237. {
  238. int l = x_limit - textWidth + 1 - x;
  239. if( l < backGroundWidth )
  240. IMGbltArea(bitmap, textWidth, 0, 0, back_ground_bitmap,
  241. l, 0, min(x_limit-x+1, backGroundWidth)-1, min(textHeight, backGroundHeight)-1 );
  242. }
  243. break;
  244. default:
  245. err_here();
  246. }
  247. }
  248. font_ptr->put_to_buffer(bitmap, textWidth, 0, 0, input_field);
  249. if( paintCursor && enable_flag && cursorX < x_limit )
  250. {
  251. // horizontal bar for selected area
  252. if( leftX < textWidth )
  253. {
  254. IMGbar( bitmap, textWidth,
  255. leftX, font_ptr->height()-1, min(rightX, textWidth-1), font_ptr->height()-1, 0);
  256. }
  257. // vertical bar
  258. if( cursorX < textWidth )
  259. IMGbar( bitmap, textWidth, cursorX, 0, cursorX, font_ptr->height()-1, 0);
  260. }
  261. if( !Vga::use_back_buf)
  262. {
  263. mouse.hide_area(x,y, x_limit, y+font_ptr->max_font_height-1 );
  264. switch( align_flag )
  265. {
  266. case 0: // left justified
  267. if( !back_ground_bitmap )
  268. {
  269. if( x+textWidth <= x_limit ) // fill right
  270. vga.blt_buf( x+textWidth, y, x_limit, y + font_ptr->max_font_height-1, 0);
  271. IMGjoinTrans(vga_front.buf_ptr(), vga_front.buf_pitch(),
  272. vga_back.buf_ptr(), vga_back.buf_pitch(),
  273. x, y, sys.common_data_buf);
  274. }
  275. else
  276. {
  277. short backGroundWidth = *(short *)back_ground_bitmap;
  278. short backGroundHeight = *(1+(short *)back_ground_bitmap);
  279. if( textWidth < backGroundWidth && x+textWidth <= x_limit ) // fill right
  280. vga_front.put_bitmap_area(x, y, back_ground_bitmap,
  281. textWidth, 0, min(x_limit-x, backGroundWidth-1), backGroundHeight-1 );
  282. vga_front.put_bitmap_trans(x, y, sys.common_data_buf);
  283. }
  284. break;
  285. case 1: // center justified
  286. if( !back_ground_bitmap )
  287. {
  288. int l = x + (x_limit - x + 1 - textWidth ) / 2;
  289. if( x < l )
  290. {
  291. vga.blt_buf( x, y, l-1, y + font_ptr->max_font_height-1, 0);
  292. }
  293. if( l+textWidth <= x_limit )
  294. {
  295. vga.blt_buf( l+textWidth, y, x_limit, y + font_ptr->max_font_height-1, 0);
  296. }
  297. IMGjoinTrans(vga_front.buf_ptr(), vga_front.buf_pitch(),
  298. vga_back.buf_ptr(), vga_back.buf_pitch(),
  299. l, y, sys.common_data_buf);
  300. }
  301. else
  302. {
  303. int l = x + (x_limit - x + 1 - textWidth ) / 2;
  304. short backGroundWidth = *(short *)back_ground_bitmap;
  305. short backGroundHeight = *(1+(short *)back_ground_bitmap);
  306. if( x < l && l-x <= backGroundWidth)
  307. {
  308. vga_front.put_bitmap_area(x, y, back_ground_bitmap,
  309. 0, 0, min(l-x, backGroundWidth)-1, backGroundHeight-1);
  310. }
  311. if( l+textWidth <= x_limit && l+textWidth-x < backGroundWidth)
  312. {
  313. vga_front.put_bitmap_area(x, y, back_ground_bitmap,
  314. l+textWidth-x, 0, min(x_limit-x+1, backGroundWidth)-1, backGroundHeight-1);
  315. }
  316. vga_front.put_bitmap_trans(l, y, sys.common_data_buf);
  317. }
  318. break;
  319. case -1: // right justified
  320. if( !back_ground_bitmap )
  321. {
  322. int l = x_limit - textWidth + 1;
  323. if( x < l ) // fill left
  324. vga.blt_buf( x, y, l-1, y + font_ptr->max_font_height-1, 0);
  325. IMGjoinTrans(vga_front.buf_ptr(), vga_front.buf_pitch(),
  326. vga_back.buf_ptr(), vga_back.buf_pitch(),
  327. l, y, sys.common_data_buf);
  328. }
  329. else
  330. {
  331. short backGroundWidth = *(short *)back_ground_bitmap;
  332. short backGroundHeight = *(1+(short *)back_ground_bitmap);
  333. int l = x_limit - textWidth + 1;
  334. if( x < l )
  335. vga_front.put_bitmap_area(0, 0, back_ground_bitmap,
  336. 0, 0, min(l-x, backGroundWidth)-1, backGroundHeight-1 );
  337. vga_front.put_bitmap_trans(l, y, sys.common_data_buf);
  338. }
  339. break;
  340. default:
  341. err_here();
  342. }
  343. mouse.show_area();
  344. }
  345. else
  346. {
  347. switch( align_flag )
  348. {
  349. case 0: // left justified
  350. IMGbltTrans( vga_back.buf_ptr(), vga_back.buf_pitch(),
  351. x, y, sys.common_data_buf);
  352. break;
  353. case 1: // center justified
  354. {
  355. int l = x + (x_limit - x + 1 - textWidth ) / 2;
  356. IMGbltTrans( vga_back.buf_ptr(), vga_back.buf_pitch(),
  357. l, y, sys.common_data_buf);
  358. }
  359. // BUGHERE : fill left and right
  360. break;
  361. case -1: // right justified
  362. IMGbltTrans( vga_back.buf_ptr(), vga_back.buf_pitch(),
  363. x_limit - textWidth + 1, y, sys.common_data_buf);
  364. break;
  365. default:
  366. err_here();
  367. }
  368. }
  369. }
  370. int GetA::cursor_x(int curPos)
  371. {
  372. switch( align_flag )
  373. {
  374. case 0: // left justified
  375. return x + font_ptr->text_width(input_field, curPos);
  376. case 1: // center justified
  377. return x + ((x_limit-x) - font_ptr->text_width(input_field))/2 + font_ptr->text_width(input_field, curPos);
  378. case -1: // right justified
  379. return x_limit - font_ptr->text_width(input_field) + font_ptr->text_width(input_field, curPos);
  380. default:
  381. err_here();
  382. return 0;
  383. }
  384. }
  385. // return 1 for selected
  386. int GetA::detect_click()
  387. {
  388. if( !enable_flag )
  389. return 0;
  390. if( !mouse_drag_flag )
  391. {
  392. int clickCount = mouse.any_click(x-font_ptr->max_font_width, y, x_limit, y+height()-1);
  393. if( clickCount == 1)
  394. {
  395. // set cursor_pos
  396. // scan from the last character, until the clicked x is
  397. // less than the character x
  398. for( cursor_pos = strlen(input_field);
  399. cursor_pos > 0 && mouse.click_x() < cursor_x(cursor_pos);
  400. --cursor_pos );
  401. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field));
  402. clear_select();
  403. mouse_drag_flag = 1;
  404. return 1;
  405. }
  406. else if( clickCount > 1 )
  407. {
  408. select_whole();
  409. return 1;
  410. }
  411. }
  412. else
  413. {
  414. if( !mouse.left_press )
  415. {
  416. mouse_drag_flag = 0;
  417. }
  418. for( cursor_pos = strlen(input_field);
  419. cursor_pos > 0 && mouse.cur_x < cursor_x(cursor_pos);
  420. --cursor_pos );
  421. err_when( cursor_pos < 0 || cursor_pos > strlen(input_field));
  422. return 1;
  423. }
  424. return 0;
  425. }
  426. unsigned GetA::detect()
  427. {
  428. unsigned keyCode = detect_key();
  429. if( keyCode )
  430. return keyCode;
  431. else
  432. return detect_click();
  433. }
  434. unsigned GetA::mark_begin()
  435. {
  436. return min( cursor_pos, mark_cursor_pos );
  437. }
  438. unsigned GetA::mark_end()
  439. {
  440. return max( cursor_pos, mark_cursor_pos );
  441. }
  442. void GetA::select_whole()
  443. {
  444. cursor_pos = strlen(input_field);
  445. mark_cursor_pos = 0;
  446. }
  447. GetAGroup::GetAGroup(int n)
  448. {
  449. geta_num = n;
  450. geta_array = new GetA[n];
  451. focused_geta = 0;
  452. enable_flag = 0;
  453. }
  454. GetAGroup::~GetAGroup()
  455. {
  456. delete[] geta_array;
  457. }
  458. void GetAGroup::paint()
  459. {
  460. for( int i = 0; i < geta_num; ++i )
  461. {
  462. geta_array[i].paint(focused_geta == i);
  463. }
  464. }
  465. int GetAGroup::detect()
  466. {
  467. if( !enable_flag )
  468. return 0;
  469. err_when( focused_geta < 0 || focused_geta > geta_num);
  470. GetA *getPtr = &geta_array[focused_geta];
  471. err_when( !getPtr->enable_flag );
  472. unsigned keyCode = getPtr->detect_key();
  473. if( keyCode )
  474. {
  475. getPtr->paint(1);
  476. // detect change field focus button
  477. if( keyCode == KEY_RETURN || keyCode == KEY_DOWN || keyCode == KEY_TAB )
  478. {
  479. set_focus(-1);
  480. }
  481. else if( keyCode == KEY_UP )
  482. {
  483. set_focus(-2);
  484. }
  485. return 1;
  486. }
  487. // detect clicking on the area
  488. for( int i = 0; i < geta_num; ++i )
  489. {
  490. getPtr = &geta_array[i];
  491. if( getPtr->detect_click() )
  492. {
  493. set_focus(i);
  494. return 1;
  495. }
  496. }
  497. return 0;
  498. }
  499. // n = -1, next
  500. // n = -2, prev
  501. // n = -3, top
  502. // n = -4, bottom
  503. int GetAGroup::set_focus(int n, int paintFlag)
  504. {
  505. int oldFocused = focused_geta;
  506. int i, newFocused;
  507. enable_flag = 1;
  508. err_when( n < -4 || n >= geta_num );
  509. switch(n)
  510. {
  511. case -1:
  512. for( i = 0, newFocused = (oldFocused+1) % geta_num;
  513. i < geta_num && !geta_array[newFocused].enable_flag;
  514. ++i, newFocused = (newFocused+1) % geta_num );
  515. break;
  516. case -2:
  517. for( i = 0, newFocused = (oldFocused+geta_num-1) % geta_num;
  518. i < geta_num && !geta_array[newFocused].enable_flag;
  519. ++i, newFocused = (newFocused+geta_num-1) % geta_num );
  520. break;
  521. case -3:
  522. for( i = 0, newFocused = 0;
  523. i < geta_num && !geta_array[newFocused].enable_flag;
  524. ++i, newFocused = (newFocused+1) % geta_num );
  525. break;
  526. case -4:
  527. for( i = 0, newFocused = geta_num-1;
  528. i < geta_num && !geta_array[newFocused].enable_flag;
  529. ++i, newFocused = (newFocused+geta_num-1) % geta_num );
  530. break;
  531. default:
  532. newFocused = n;
  533. }
  534. err_when( !geta_array[newFocused].enable_flag );
  535. focused_geta = newFocused;
  536. if( paintFlag )
  537. {
  538. if( oldFocused != newFocused )
  539. geta_array[oldFocused].paint(0);
  540. geta_array[newFocused].paint(1);
  541. }
  542. return 1;
  543. }
  544. GetA& GetAGroup::operator[](int n)
  545. {
  546. err_when( n < 0 || n >= geta_num);
  547. return geta_array[n];
  548. }
  549. int GetAGroup::operator()()
  550. {
  551. return focused_geta;
  552. }