#include "ui_local.h" #ifndef UI_HARD_LINKED // Cash: rename these functions to not clash /* =================== Field_Draw Handles horizontal scrolling and cursor blinking x, y, amd width are in pixels =================== */ void Field_Draw( field_t *edit, int x, int y, int width, int size,int color,int color2, qboolean showCursor ) { int len; int drawLen; int prestep; int cursorChar; char str[MAX_STRING_CHARS]; int style; int finalColor; drawLen = edit->widthInChars; len = strlen( edit->buffer ) + 1; // guarantee that cursor will be visible if ( len <= drawLen ) { prestep = 0; } else { if ( edit->scroll + drawLen > len ) { edit->scroll = len - drawLen; if ( edit->scroll < 0 ) { edit->scroll = 0; } } prestep = edit->scroll; } if ( prestep + drawLen > len ) { drawLen = len - prestep; } // extract characters from the field at if ( drawLen >= MAX_STRING_CHARS ) { ui.Error( ERR_DROP, "drawLen >= MAX_STRING_CHARS" ); } memcpy( str, edit->buffer + prestep, drawLen ); str[ drawLen ] = 0; if (showCursor) { // style = UI_LEFT|UI_PULSE; style = UI_LEFT; finalColor = color2; } else { style = UI_LEFT; finalColor = color; } // draw it if ( size == SMALLCHAR_WIDTH ) { UI_DrawString( x, y, str, UI_LEFT|UI_SMALLFONT, colorTable[finalColor] ); } else { // draw big string with drop shadow UI_DrawString( x, y, str, style, colorTable[finalColor] ); } // draw the cursor if ( !showCursor ) { return; } if ( ( uis.realtime >> 8 ) & 1 ) { return; // off blink } if ( ui.Key_GetOverstrikeMode() ) { cursorChar = 11; } else { cursorChar = 10; } if ( size == SMALLCHAR_WIDTH ) { ui.R_SetColor( colorTable[CT_YELLOW]); UI_DrawHandlePic( x + ( edit->cursor - prestep ) * size, y + (SMALLCHAR_HEIGHT - 2), 10, 3, uis.whiteShader); // UI_DrawChar( x + ( edit->cursor - prestep ) * size, y, cursorChar, UI_LEFT|UI_SMALLFONT, menu_text_color ); } else { ui.R_SetColor( colorTable[CT_YELLOW]); UI_DrawHandlePic( x + ( edit->cursor - prestep ) * size, y, 10, 3, uis.whiteShader); // UI_DrawChar( x + ( edit->cursor - prestep ) * size, y, cursorChar, style, color ); } } /* ================ Field_Paste ================ */ void Field_Paste( field_t *edit ) { char pasteBuffer[64]; int pasteLen, i; ui.GetClipboardData( pasteBuffer, 64 ); // send as if typed, so insert / overstrike works properly pasteLen = strlen( pasteBuffer ); for ( i = 0 ; i < pasteLen ; i++ ) { Field_CharEvent( edit, pasteBuffer[i] ); } } /* ================= Field_KeyDownEvent Performs the basic line editing functions for the console, in-game talk, and menu fields Key events are used for non-printable characters, others are gotten from char events. ================= */ void Field_KeyDownEvent( field_t *edit, int key ) { int len; // shift-insert is paste if ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && ui.Key_IsDown( K_SHIFT ) ) { Field_Paste( edit ); return; } len = strlen( edit->buffer ); if ( key == K_DEL ) { if ( edit->cursor < len ) { memmove( edit->buffer + edit->cursor, edit->buffer + edit->cursor + 1, len - edit->cursor ); } return; } if ( key == K_RIGHTARROW ) { if ( edit->cursor < len ) { edit->cursor++; } if ( edit->cursor >= edit->scroll + edit->widthInChars && edit->cursor <= len ) { edit->scroll++; } return; } if ( key == K_LEFTARROW ) { if ( edit->cursor > 0 ) { edit->cursor--; } if ( edit->cursor < edit->scroll ) { edit->scroll--; } return; } if ( key == K_HOME || ( tolower(key) == 'a' && ui.Key_IsDown( K_CTRL ) ) ) { edit->cursor = 0; return; } if ( key == K_END || ( tolower(key) == 'e' && ui.Key_IsDown( K_CTRL ) ) ) { edit->cursor = len; return; } if ( key == K_INS ) { ui.Key_SetOverstrikeMode( !ui.Key_GetOverstrikeMode() ); return; } } /* ================== Field_CharEvent ================== */ void Field_CharEvent( field_t *edit, int ch ) { int len; if ( ch == 'v' - 'a' + 1 ) { // ctrl-v is paste Field_Paste( edit ); return; } if ( ch == 'c' - 'a' + 1 ) { // ctrl-c clears the field Field_Clear( edit ); return; } len = strlen( edit->buffer ); if ( ch == 'h' - 'a' + 1 ) { // ctrl-h is backspace if ( edit->cursor > 0 ) { memmove( edit->buffer + edit->cursor - 1, edit->buffer + edit->cursor, len + 1 - edit->cursor ); edit->cursor--; if ( edit->cursor < edit->scroll ) { edit->scroll--; } } return; } if ( ch == 'a' - 'a' + 1 ) { // ctrl-a is home edit->cursor = 0; edit->scroll = 0; return; } if ( ch == 'e' - 'a' + 1 ) { // ctrl-e is end edit->cursor = len; edit->scroll = edit->cursor - edit->widthInChars; return; } // // ignore any other non printable chars // if ( ch < 32 ) { return; } if ( !ui.Key_GetOverstrikeMode() ) { if ((edit->cursor == MAX_EDIT_LINE - 1) || (edit->maxchars && edit->cursor >= edit->maxchars)) return; } else { // insert mode if (( len == MAX_EDIT_LINE - 1 ) || (edit->maxchars && len >= edit->maxchars)) return; memmove( edit->buffer + edit->cursor + 1, edit->buffer + edit->cursor, len + 1 - edit->cursor ); } edit->buffer[edit->cursor] = ch; if (!edit->maxchars || edit->cursor < edit->maxchars-1) edit->cursor++; if ( edit->cursor >= edit->widthInChars ) { edit->scroll++; } if ( edit->cursor == len + 1) { edit->buffer[edit->cursor] = 0; } } /* ================== Field_Clear ================== */ void Field_Clear( field_t *edit ) { edit->buffer[0] = 0; edit->cursor = 0; edit->scroll = 0; } #endif /* ================== MenuField_Init ================== */ void MenuField_Init( menufield_s* m ) { int l; Field_Clear( &m->field ); if (m->generic.name) { l = (strlen( m->generic.name )+1) * SMALLCHAR_WIDTH; } else { l = 0; } m->generic.left = m->generic.x - l; m->generic.top = m->generic.y - SMALLCHAR_HEIGHT/4; m->generic.right = m->generic.x + m->field.widthInChars*SMALLCHAR_WIDTH; m->generic.bottom = m->generic.y + SMALLCHAR_HEIGHT + SMALLCHAR_HEIGHT/4; } /* ================== MenuField_Draw ================== */ void MenuField_Draw( menufield_s *f ) { float x; qboolean focus; if (Menu_ItemAtCursor( f->generic.parent ) == f) { focus = qtrue; } else { focus = qfalse; } if ( f->field.textEnum ) { // UI_DrawString( f->generic.x - BIGCHAR_WIDTH, f->generic.y, f->generic.name, UI_RIGHT, focus ? menu_highlight_color : menu_dark_color ); UI_DrawProportionalString( f->generic.x - 10, f->generic.y, menu_normal_text[f->field.textEnum],UI_RIGHT | UI_SMALLFONT, colorTable[CT_BLACK]); } x = f->generic.x; Field_Draw( &f->field, x + SMALLCHAR_WIDTH, f->generic.y, f->field.widthInChars*SMALLCHAR_WIDTH, SMALLCHAR_WIDTH,f->field.textcolor,f->field.textcolor2, focus ); }