/* * Seven Kingdoms: Ancient Adversaries * * Copyright 1997,1998 Enlight Software Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ // Filename : OGETA.CPP // Description : simple get field #include #include #include #include #include #include #include GetA::GetA() { input_field = NULL; field_len = 0; font_ptr = NULL; align_flag = 0; enable_flag = 1; mouse_drag_flag = 0; back_ground_bitmap = NULL; } void GetA::init( int x1, int y1, int x2, char *field, unsigned length, Font *fontPtr, char align, char detectEsc) { x = x1; y = y1; x_limit = x2; input_field = field; field_len = length; font_ptr = fontPtr; align_flag = align; enable_flag = 1; esc_key_flag = detectEsc; mouse_drag_flag = 0; back_ground_bitmap = NULL; select_whole(); } int GetA::height() { return font_ptr->max_font_height; } void GetA::clear() { input_field[0] = '\0'; cursor_pos = 0; clear_select(); } // return 0 for no input // return key code pressed such as KEY_RETURN, KEY_ESCAPE ... unsigned GetA::detect_key() { if( !enable_flag ) return 0; err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); if( mouse.is_key_event() ) { unsigned keyCode = mouse.key_code; unsigned shiftPressed = mouse.event_skey_state & SHIFT_KEY_MASK; // printable character if( keyCode >= ' ' && keyCode <= 0xff ) { if( strlen(input_field)-(mark_end() - mark_begin()) < field_len) { // insert character memmove( input_field+mark_begin()+1, input_field+mark_end(), strlen(input_field)-mark_end()+1); input_field[mark_begin()] = keyCode; cursor_pos = mark_begin()+1; clear_select(); } err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } else if( keyCode == KEY_DEL ) { if( is_select() ) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); // erase selected area memmove( input_field+mark_begin(), input_field+mark_end(), strlen(input_field)-mark_end()+1); cursor_pos = mark_begin(); clear_select(); } else { if(strlen(input_field) > cursor_pos) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); memmove( input_field+cursor_pos, input_field+cursor_pos+1, strlen(input_field)-cursor_pos); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); } } err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } else if( keyCode == KEY_BACK_SPACE ) { if( is_select() ) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); // erase selected area memmove( input_field+mark_begin(), input_field+mark_end(), strlen(input_field)-mark_end()+1); cursor_pos = mark_begin(); clear_select(); } else { if(cursor_pos > 0) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); memmove( input_field+cursor_pos-1, input_field+cursor_pos, strlen(input_field)-cursor_pos+1); cursor_pos--; err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); clear_select(); } } err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( keyCode == KEY_LEFT ) { if(cursor_pos > 0) cursor_pos--; if( !shiftPressed ) clear_select(); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( keyCode == KEY_RIGHT ) { if(cursor_pos < strlen(input_field)) cursor_pos++; if( !shiftPressed ) clear_select(); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( keyCode == KEY_HOME) { cursor_pos = 0; if( !shiftPressed ) clear_select(); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( keyCode == KEY_END) { cursor_pos = strlen(input_field); if( !shiftPressed ) clear_select(); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); return keyCode; } if( esc_key_flag && keyCode == KEY_ESC ) { // if esc_key_flag is 0 and ESC key pressed, still return 0 clear(); return keyCode; } if( keyCode == KEY_RETURN || keyCode == KEY_UP || keyCode == KEY_DOWN || keyCode == KEY_TAB ) { return keyCode; } } return 0; } void GetA::paint(int paintCursor) { err_when( cursor_pos < 0 || cursor_pos > strlen(input_field) ); err_when( mark_cursor_pos < 0 || mark_cursor_pos > strlen(input_field) ); int cursorX = font_ptr->text_width(input_field, cursor_pos); int leftX = font_ptr->text_width(input_field, mark_begin()); int rightX = font_ptr->text_width(input_field, mark_end()); // create a temp buffer to store character int rightLimit = x_limit - x; int textWidth = font_ptr->text_width(input_field, -1, rightLimit ) + 1; int textHeight = font_ptr->max_font_height; char *bitmap = sys.common_data_buf; err_when( 2*sizeof(short) + textWidth * textHeight > COMMON_DATA_BUF_SIZE ); *(short *)bitmap = textWidth; bitmap += sizeof(short); *(short *)bitmap = textHeight; bitmap += sizeof(short); memset( bitmap, TRANSPARENT_CODE, textWidth * textHeight ); if( back_ground_bitmap && !Vga::use_back_buf ) { short backGroundWidth = *(short *)back_ground_bitmap; short backGroundHeight = *(1+(short *)back_ground_bitmap); // fill backGround switch(align_flag) { case 0: IMGbltArea(bitmap, textWidth, 0, 0, back_ground_bitmap, 0, 0, min(textWidth, backGroundWidth)-1, min(textHeight, backGroundHeight)-1 ); break; case 1: { int l = (x_limit - x + 1 - textWidth ) / 2; if( l >= 0 && l < backGroundWidth ) IMGbltArea(bitmap, textWidth, 0, 0, back_ground_bitmap, l, 0, min(l+textWidth, backGroundWidth)-1, min(textHeight, backGroundHeight)-1 ); } break; case -1: { int l = x_limit - textWidth + 1 - x; if( l < backGroundWidth ) IMGbltArea(bitmap, textWidth, 0, 0, back_ground_bitmap, l, 0, min(x_limit-x+1, backGroundWidth)-1, min(textHeight, backGroundHeight)-1 ); } break; default: err_here(); } } font_ptr->put_to_buffer(bitmap, textWidth, 0, 0, input_field); if( paintCursor && enable_flag && cursorX < x_limit ) { // horizontal bar for selected area if( leftX < textWidth ) { IMGbar( bitmap, textWidth, leftX, font_ptr->height()-1, min(rightX, textWidth-1), font_ptr->height()-1, 0); } // vertical bar if( cursorX < textWidth ) IMGbar( bitmap, textWidth, cursorX, 0, cursorX, font_ptr->height()-1, 0); } if( !Vga::use_back_buf) { mouse.hide_area(x,y, x_limit, y+font_ptr->max_font_height-1 ); switch( align_flag ) { case 0: // left justified if( !back_ground_bitmap ) { if( x+textWidth <= x_limit ) // fill right vga.blt_buf( x+textWidth, y, x_limit, y + font_ptr->max_font_height-1, 0); IMGjoinTrans(vga_front.buf_ptr(), vga_front.buf_pitch(), vga_back.buf_ptr(), vga_back.buf_pitch(), x, y, sys.common_data_buf); } else { short backGroundWidth = *(short *)back_ground_bitmap; short backGroundHeight = *(1+(short *)back_ground_bitmap); if( textWidth < backGroundWidth && x+textWidth <= x_limit ) // fill right vga_front.put_bitmap_area(x, y, back_ground_bitmap, textWidth, 0, min(x_limit-x, backGroundWidth-1), backGroundHeight-1 ); vga_front.put_bitmap_trans(x, y, sys.common_data_buf); } break; case 1: // center justified if( !back_ground_bitmap ) { int l = x + (x_limit - x + 1 - textWidth ) / 2; if( x < l ) { vga.blt_buf( x, y, l-1, y + font_ptr->max_font_height-1, 0); } if( l+textWidth <= x_limit ) { vga.blt_buf( l+textWidth, y, x_limit, y + font_ptr->max_font_height-1, 0); } IMGjoinTrans(vga_front.buf_ptr(), vga_front.buf_pitch(), vga_back.buf_ptr(), vga_back.buf_pitch(), l, y, sys.common_data_buf); } else { int l = x + (x_limit - x + 1 - textWidth ) / 2; short backGroundWidth = *(short *)back_ground_bitmap; short backGroundHeight = *(1+(short *)back_ground_bitmap); if( x < l && l-x <= backGroundWidth) { vga_front.put_bitmap_area(x, y, back_ground_bitmap, 0, 0, min(l-x, backGroundWidth)-1, backGroundHeight-1); } if( l+textWidth <= x_limit && l+textWidth-x < backGroundWidth) { vga_front.put_bitmap_area(x, y, back_ground_bitmap, l+textWidth-x, 0, min(x_limit-x+1, backGroundWidth)-1, backGroundHeight-1); } vga_front.put_bitmap_trans(l, y, sys.common_data_buf); } break; case -1: // right justified if( !back_ground_bitmap ) { int l = x_limit - textWidth + 1; if( x < l ) // fill left vga.blt_buf( x, y, l-1, y + font_ptr->max_font_height-1, 0); IMGjoinTrans(vga_front.buf_ptr(), vga_front.buf_pitch(), vga_back.buf_ptr(), vga_back.buf_pitch(), l, y, sys.common_data_buf); } else { short backGroundWidth = *(short *)back_ground_bitmap; short backGroundHeight = *(1+(short *)back_ground_bitmap); int l = x_limit - textWidth + 1; if( x < l ) vga_front.put_bitmap_area(0, 0, back_ground_bitmap, 0, 0, min(l-x, backGroundWidth)-1, backGroundHeight-1 ); vga_front.put_bitmap_trans(l, y, sys.common_data_buf); } break; default: err_here(); } mouse.show_area(); } else { switch( align_flag ) { case 0: // left justified IMGbltTrans( vga_back.buf_ptr(), vga_back.buf_pitch(), x, y, sys.common_data_buf); break; case 1: // center justified { int l = x + (x_limit - x + 1 - textWidth ) / 2; IMGbltTrans( vga_back.buf_ptr(), vga_back.buf_pitch(), l, y, sys.common_data_buf); } // BUGHERE : fill left and right break; case -1: // right justified IMGbltTrans( vga_back.buf_ptr(), vga_back.buf_pitch(), x_limit - textWidth + 1, y, sys.common_data_buf); break; default: err_here(); } } } int GetA::cursor_x(int curPos) { switch( align_flag ) { case 0: // left justified return x + font_ptr->text_width(input_field, curPos); case 1: // center justified return x + ((x_limit-x) - font_ptr->text_width(input_field))/2 + font_ptr->text_width(input_field, curPos); case -1: // right justified return x_limit - font_ptr->text_width(input_field) + font_ptr->text_width(input_field, curPos); default: err_here(); return 0; } } // return 1 for selected int GetA::detect_click() { if( !enable_flag ) return 0; if( !mouse_drag_flag ) { int clickCount = mouse.any_click(x-font_ptr->max_font_width, y, x_limit, y+height()-1); if( clickCount == 1) { // set cursor_pos // scan from the last character, until the clicked x is // less than the character x for( cursor_pos = strlen(input_field); cursor_pos > 0 && mouse.click_x() < cursor_x(cursor_pos); --cursor_pos ); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field)); clear_select(); mouse_drag_flag = 1; return 1; } else if( clickCount > 1 ) { select_whole(); return 1; } } else { if( !mouse.left_press ) { mouse_drag_flag = 0; } for( cursor_pos = strlen(input_field); cursor_pos > 0 && mouse.cur_x < cursor_x(cursor_pos); --cursor_pos ); err_when( cursor_pos < 0 || cursor_pos > strlen(input_field)); return 1; } return 0; } unsigned GetA::detect() { unsigned keyCode = detect_key(); if( keyCode ) return keyCode; else return detect_click(); } unsigned GetA::mark_begin() { return min( cursor_pos, mark_cursor_pos ); } unsigned GetA::mark_end() { return max( cursor_pos, mark_cursor_pos ); } void GetA::select_whole() { cursor_pos = strlen(input_field); mark_cursor_pos = 0; } GetAGroup::GetAGroup(int n) { geta_num = n; geta_array = new GetA[n]; focused_geta = 0; enable_flag = 0; } GetAGroup::~GetAGroup() { delete[] geta_array; } void GetAGroup::paint() { for( int i = 0; i < geta_num; ++i ) { geta_array[i].paint(focused_geta == i); } } int GetAGroup::detect() { if( !enable_flag ) return 0; err_when( focused_geta < 0 || focused_geta > geta_num); GetA *getPtr = &geta_array[focused_geta]; err_when( !getPtr->enable_flag ); unsigned keyCode = getPtr->detect_key(); if( keyCode ) { getPtr->paint(1); // detect change field focus button if( keyCode == KEY_RETURN || keyCode == KEY_DOWN || keyCode == KEY_TAB ) { set_focus(-1); } else if( keyCode == KEY_UP ) { set_focus(-2); } return 1; } // detect clicking on the area for( int i = 0; i < geta_num; ++i ) { getPtr = &geta_array[i]; if( getPtr->detect_click() ) { set_focus(i); return 1; } } return 0; } // n = -1, next // n = -2, prev // n = -3, top // n = -4, bottom int GetAGroup::set_focus(int n, int paintFlag) { int oldFocused = focused_geta; int i, newFocused; enable_flag = 1; err_when( n < -4 || n >= geta_num ); switch(n) { case -1: for( i = 0, newFocused = (oldFocused+1) % geta_num; i < geta_num && !geta_array[newFocused].enable_flag; ++i, newFocused = (newFocused+1) % geta_num ); break; case -2: for( i = 0, newFocused = (oldFocused+geta_num-1) % geta_num; i < geta_num && !geta_array[newFocused].enable_flag; ++i, newFocused = (newFocused+geta_num-1) % geta_num ); break; case -3: for( i = 0, newFocused = 0; i < geta_num && !geta_array[newFocused].enable_flag; ++i, newFocused = (newFocused+1) % geta_num ); break; case -4: for( i = 0, newFocused = geta_num-1; i < geta_num && !geta_array[newFocused].enable_flag; ++i, newFocused = (newFocused+geta_num-1) % geta_num ); break; default: newFocused = n; } err_when( !geta_array[newFocused].enable_flag ); focused_geta = newFocused; if( paintFlag ) { if( oldFocused != newFocused ) geta_array[oldFocused].paint(0); geta_array[newFocused].paint(1); } return 1; } GetA& GetAGroup::operator[](int n) { err_when( n < 0 || n >= geta_num); return geta_array[n]; } int GetAGroup::operator()() { return focused_geta; }