📄 ui_qmenu.c
字号:
if (c == key)
{
// set current item, mimic windows listbox scroll behavior
if (j < l->top)
{
// behind top most item, set this as new top
l->top = j;
}
else if (j > l->top+l->height-1)
{
// past end of list box, do page down
l->top = (j+1) - l->height;
}
if (l->curvalue != j)
{
l->oldvalue = l->curvalue;
l->curvalue = j;
if (l->generic.callback)
l->generic.callback( l, QM_GOTFOCUS );
return ( menu_move_sound );
}
return (menu_buzz_sound);
}
}
return (menu_buzz_sound);
}
/*
=================
ScrollList_Draw
=================
*/
void ScrollList_Draw( menulist_s *l )
{
int x;
int u;
int y;
int i;
int base;
int column;
float* color;
qboolean hasfocus;
int style;
hasfocus = (l->generic.parent->cursor == l->generic.menuPosition);
x = l->generic.x;
for( column = 0; column < l->columns; column++ ) {
y = l->generic.y;
base = l->top + column * l->height;
for( i = base; i < base + l->height; i++) {
if (i >= l->numitems)
break;
if (i == l->curvalue)
{
u = x - 2;
if( l->generic.flags & QMF_CENTER_JUSTIFY ) {
u -= (l->width * SMALLCHAR_WIDTH) / 2 + 1;
}
UI_FillRect(u,y,l->width*SMALLCHAR_WIDTH,SMALLCHAR_HEIGHT+2,listbar_color);
color = text_color_highlight;
if (hasfocus)
style = UI_PULSE|UI_LEFT|UI_SMALLFONT;
else
style = UI_LEFT|UI_SMALLFONT;
}
else
{
color = text_color_normal;
style = UI_LEFT|UI_SMALLFONT;
}
if( l->generic.flags & QMF_CENTER_JUSTIFY ) {
style |= UI_CENTER;
}
UI_DrawString(
x,
y,
l->itemnames[i],
style,
color);
y += SMALLCHAR_HEIGHT;
}
x += (l->width + l->seperation) * SMALLCHAR_WIDTH;
}
}
/*
=================
Menu_AddItem
=================
*/
void Menu_AddItem( menuframework_s *menu, void *item )
{
menucommon_s *itemptr;
if (menu->nitems >= MAX_MENUITEMS)
trap_Error ("Menu_AddItem: excessive items");
menu->items[menu->nitems] = item;
((menucommon_s*)menu->items[menu->nitems])->parent = menu;
((menucommon_s*)menu->items[menu->nitems])->menuPosition = menu->nitems;
((menucommon_s*)menu->items[menu->nitems])->flags &= ~QMF_HASMOUSEFOCUS;
// perform any item specific initializations
itemptr = (menucommon_s*)item;
if (!(itemptr->flags & QMF_NODEFAULTINIT))
{
switch (itemptr->type)
{
case MTYPE_ACTION:
Action_Init((menuaction_s*)item);
break;
case MTYPE_FIELD:
MenuField_Init((menufield_s*)item);
break;
case MTYPE_SPINCONTROL:
SpinControl_Init((menulist_s*)item);
break;
case MTYPE_RADIOBUTTON:
RadioButton_Init((menuradiobutton_s*)item);
break;
case MTYPE_SLIDER:
Slider_Init((menuslider_s*)item);
break;
case MTYPE_BITMAP:
Bitmap_Init((menubitmap_s*)item);
break;
case MTYPE_TEXT:
Text_Init((menutext_s*)item);
break;
case MTYPE_SCROLLLIST:
ScrollList_Init((menulist_s*)item);
break;
case MTYPE_PTEXT:
PText_Init((menutext_s*)item);
break;
case MTYPE_BTEXT:
BText_Init((menutext_s*)item);
break;
default:
trap_Error( va("Menu_Init: unknown type %d", itemptr->type) );
}
}
menu->nitems++;
}
/*
=================
Menu_CursorMoved
=================
*/
void Menu_CursorMoved( menuframework_s *m )
{
void (*callback)( void *self, int notification );
if (m->cursor_prev == m->cursor)
return;
if (m->cursor_prev >= 0 && m->cursor_prev < m->nitems)
{
callback = ((menucommon_s*)(m->items[m->cursor_prev]))->callback;
if (callback)
callback(m->items[m->cursor_prev],QM_LOSTFOCUS);
}
if (m->cursor >= 0 && m->cursor < m->nitems)
{
callback = ((menucommon_s*)(m->items[m->cursor]))->callback;
if (callback)
callback(m->items[m->cursor],QM_GOTFOCUS);
}
}
/*
=================
Menu_SetCursor
=================
*/
void Menu_SetCursor( menuframework_s *m, int cursor )
{
if (((menucommon_s*)(m->items[cursor]))->flags & (QMF_GRAYED|QMF_INACTIVE))
{
// cursor can't go there
return;
}
m->cursor_prev = m->cursor;
m->cursor = cursor;
Menu_CursorMoved( m );
}
/*
=================
Menu_SetCursorToItem
=================
*/
void Menu_SetCursorToItem( menuframework_s *m, void* ptr )
{
int i;
for (i=0; i<m->nitems; i++)
{
if (m->items[i] == ptr)
{
Menu_SetCursor( m, i );
return;
}
}
}
/*
** Menu_AdjustCursor
**
** This function takes the given menu, the direction, and attempts
** to adjust the menu's cursor so that it's at the next available
** slot.
*/
void Menu_AdjustCursor( menuframework_s *m, int dir ) {
menucommon_s *item = NULL;
qboolean wrapped = qfalse;
wrap:
while ( m->cursor >= 0 && m->cursor < m->nitems ) {
item = ( menucommon_s * ) m->items[m->cursor];
if (( item->flags & (QMF_GRAYED|QMF_MOUSEONLY|QMF_INACTIVE) ) ) {
m->cursor += dir;
}
else {
break;
}
}
if ( dir == 1 ) {
if ( m->cursor >= m->nitems ) {
if ( m->wrapAround ) {
if ( wrapped ) {
m->cursor = m->cursor_prev;
return;
}
m->cursor = 0;
wrapped = qtrue;
goto wrap;
}
m->cursor = m->cursor_prev;
}
}
else {
if ( m->cursor < 0 ) {
if ( m->wrapAround ) {
if ( wrapped ) {
m->cursor = m->cursor_prev;
return;
}
m->cursor = m->nitems - 1;
wrapped = qtrue;
goto wrap;
}
m->cursor = m->cursor_prev;
}
}
}
/*
=================
Menu_Draw
=================
*/
void Menu_Draw( menuframework_s *menu )
{
int i;
menucommon_s *itemptr;
// draw menu
for (i=0; i<menu->nitems; i++)
{
itemptr = (menucommon_s*)menu->items[i];
if (itemptr->flags & QMF_HIDDEN)
continue;
if (itemptr->ownerdraw)
{
// total subclassing, owner draws everything
itemptr->ownerdraw( itemptr );
}
else
{
switch (itemptr->type)
{
case MTYPE_RADIOBUTTON:
RadioButton_Draw( (menuradiobutton_s*)itemptr );
break;
case MTYPE_FIELD:
MenuField_Draw( (menufield_s*)itemptr );
break;
case MTYPE_SLIDER:
Slider_Draw( (menuslider_s*)itemptr );
break;
case MTYPE_SPINCONTROL:
SpinControl_Draw( (menulist_s*)itemptr );
break;
case MTYPE_ACTION:
Action_Draw( (menuaction_s*)itemptr );
break;
case MTYPE_BITMAP:
Bitmap_Draw( (menubitmap_s*)itemptr );
break;
case MTYPE_TEXT:
Text_Draw( (menutext_s*)itemptr );
break;
case MTYPE_SCROLLLIST:
ScrollList_Draw( (menulist_s*)itemptr );
break;
case MTYPE_PTEXT:
PText_Draw( (menutext_s*)itemptr );
break;
case MTYPE_BTEXT:
BText_Draw( (menutext_s*)itemptr );
break;
default:
trap_Error( va("Menu_Draw: unknown type %d", itemptr->type) );
}
}
#ifndef NDEBUG
if( uis.debug ) {
int x;
int y;
int w;
int h;
if( !( itemptr->flags & QMF_INACTIVE ) ) {
x = itemptr->left;
y = itemptr->top;
w = itemptr->right - itemptr->left + 1;
h = itemptr->bottom - itemptr->top + 1;
if (itemptr->flags & QMF_HASMOUSEFOCUS) {
UI_DrawRect(x, y, w, h, colorYellow );
}
else {
UI_DrawRect(x, y, w, h, colorWhite );
}
}
}
#endif
}
itemptr = Menu_ItemAtCursor( menu );
if ( itemptr && itemptr->statusbar)
itemptr->statusbar( ( void * ) itemptr );
}
/*
=================
Menu_ItemAtCursor
=================
*/
void *Menu_ItemAtCursor( menuframework_s *m )
{
if ( m->cursor < 0 || m->cursor >= m->nitems )
return 0;
return m->items[m->cursor];
}
/*
=================
Menu_ActivateItem
=================
*/
sfxHandle_t Menu_ActivateItem( menuframework_s *s, menucommon_s* item ) {
if ( item->callback ) {
item->callback( item, QM_ACTIVATED );
if( !( item->flags & QMF_SILENT ) ) {
return menu_move_sound;
}
}
return 0;
}
/*
=================
Menu_DefaultKey
=================
*/
sfxHandle_t Menu_DefaultKey( menuframework_s *m, int key )
{
sfxHandle_t sound = 0;
menucommon_s *item;
int cursor_prev;
// menu system keys
switch ( key )
{
case K_MOUSE2:
case K_ESCAPE:
UI_PopMenu();
return menu_out_sound;
}
if (!m || !m->nitems)
return 0;
// route key stimulus to widget
item = Menu_ItemAtCursor( m );
if (item && !(item->flags & (QMF_GRAYED|QMF_INACTIVE)))
{
switch (item->type)
{
case MTYPE_SPINCONTROL:
sound = SpinControl_Key( (menulist_s*)item, key );
break;
case MTYPE_RADIOBUTTON:
sound = RadioButton_Key( (menuradiobutton_s*)item, key );
break;
case MTYPE_SLIDER:
sound = Slider_Key( (menuslider_s*)item, key );
break;
case MTYPE_SCROLLLIST:
sound = ScrollList_Key( (menulist_s*)item, key );
break;
case MTYPE_FIELD:
sound = MenuField_Key( (menufield_s*)item, &key );
break;
}
if (sound) {
// key was handled
return sound;
}
}
// default handling
switch ( key )
{
#ifndef NDEBUG
case K_F11:
uis.debug ^= 1;
break;
case K_F12:
trap_Cmd_ExecuteText(EXEC_APPEND, "screenshot\n");
break;
#endif
case K_KP_UPARROW:
case K_UPARROW:
cursor_prev = m->cursor;
m->cursor_prev = m->cursor;
m->cursor--;
Menu_AdjustCursor( m, -1 );
if ( cursor_prev != m->cursor ) {
Menu_CursorMoved( m );
sound = menu_move_sound;
}
break;
case K_TAB:
case K_KP_DOWNARROW:
case K_DOWNARROW:
cursor_prev = m->cursor;
m->cursor_prev = m->cursor;
m->cursor++;
Menu_AdjustCursor( m, 1 );
if ( cursor_prev != m->cursor ) {
Menu_CursorMoved( m );
sound = menu_move_sound;
}
break;
case K_MOUSE1:
case K_MOUSE3:
if (item)
if ((item->flags & QMF_HASMOUSEFOCUS) && !(item->flags & (QMF_GRAYED|QMF_INACTIVE)))
return (Menu_ActivateItem( m, item ));
break;
case K_JOY1:
case K_JOY2:
case K_JOY3:
case K_JOY4:
case K_AUX1:
case K_AUX2:
case K_AUX3:
case K_AUX4:
case K_AUX5:
case K_AUX6:
case K_AUX7:
case K_AUX8:
case K_AUX9:
case K_AUX10:
case K_AUX11:
case K_AUX12:
case K_AUX13:
case K_AUX14:
case K_AUX15:
case K_AUX16:
case K_KP_ENTER:
case K_ENTER:
if (item)
if (!(item->flags & (QMF_MOUSEONLY|QMF_GRAYED|QMF_INACTIVE)))
return (Menu_ActivateItem( m, item ));
break;
}
return sound;
}
/*
=================
Menu_Cache
=================
*/
void Menu_Cache( void )
{
uis.charset = trap_R_RegisterShaderNoMip( "gfx/2d/bigchars" );
uis.charsetProp = trap_R_RegisterShaderNoMip( "menu/art/font1_prop.tga" );
uis.charsetPropGlow = trap_R_RegisterShaderNoMip( "menu/art/font1_prop_glo.tga" );
uis.charsetPropB = trap_R_RegisterShaderNoMip( "menu/art/font2_prop.tga" );
uis.cursor = trap_R_RegisterShaderNoMip( "menu/art/3_cursor2" );
uis.rb_on = trap_R_RegisterShaderNoMip( "menu/art/switch_on" );
uis.rb_off = trap_R_RegisterShaderNoMip( "menu/art/switch_off" );
uis.whiteShader = trap_R_RegisterShaderNoMip( "white" );
if ( uis.glconfig.hardwareType == GLHW_RAGEPRO ) {
// the blend effect turns to shit with the normal
uis.menuBackShader = trap_R_RegisterShaderNoMip( "menubackRagePro" );
} else {
uis.menuBackShader = trap_R_RegisterShaderNoMip( "menuback" );
}
uis.menuBackNoLogoShader = trap_R_RegisterShaderNoMip( "menubacknologo" );
menu_in_sound = trap_S_RegisterSound( "sound/misc/menu1.wav", qfalse );
menu_move_sound = trap_S_RegisterSound( "sound/misc/menu2.wav", qfalse );
menu_out_sound = trap_S_RegisterSound( "sound/misc/menu3.wav", qfalse );
menu_buzz_sound = trap_S_RegisterSound( "sound/misc/menu4.wav", qfalse );
weaponChangeSound = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse );
// need a nonzero sound, make an empty sound for this
menu_null_sound = -1;
sliderBar = trap_R_RegisterShaderNoMip( "menu/art/slider2" );
sliderButton_0 = trap_R_RegisterShaderNoMip( "menu/art/sliderbutt_0" );
sliderButton_1 = trap_R_RegisterShaderNoMip( "menu/art/sliderbutt_1" );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -