summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2009-11-15 01:10:27 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:17:19 +0000
commit8f759de26ac1a17676f3937019804b3a9a972e35 (patch)
tree4182465207276ea0b51051b6e9d6ad992b07f74d /src/ui
parent00043d33bad26cedbfa105269ae2b1b66684b721 (diff)
* s/ITEM_TYPE_COMBO/ITEM_TYPE_CYCLE/
* Add ITEM_TYPE_COMBOBOX -- a proper combobox widget * Use ITEM_TYPE_COMBOBOX for video mode selection * General refactoring of the listbox code * Various other assorted tidy-ups
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/ui_local.h57
-rw-r--r--src/ui/ui_main.c149
-rw-r--r--src/ui/ui_shared.c1405
-rw-r--r--src/ui/ui_shared.h96
4 files changed, 815 insertions, 892 deletions
diff --git a/src/ui/ui_local.h b/src/ui/ui_local.h
index 46210d02..71e568fe 100644
--- a/src/ui/ui_local.h
+++ b/src/ui/ui_local.h
@@ -291,7 +291,8 @@ typedef struct
int nextFindPlayerRefresh;
resolution_t resolutions[ MAX_RESOLUTIONS ];
- int numResolutions;
+ int numResolutions;
+ int resolutionIndex;
qboolean inGameLoad;
@@ -315,28 +316,28 @@ void UI_FillRect( float x, float y, float width, float height, const float
//
void trap_Print( const char *string );
void trap_Error( const char *string );
-int trap_Milliseconds( void );
+int trap_Milliseconds( void );
void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags );
void trap_Cvar_Update( vmCvar_t *vmCvar );
void trap_Cvar_Set( const char *var_name, const char *value );
-float trap_Cvar_VariableValue( const char *var_name );
+float trap_Cvar_VariableValue( const char *var_name );
void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
void trap_Cvar_SetValue( const char *var_name, float value );
void trap_Cvar_Reset( const char *name );
void trap_Cvar_Create( const char *var_name, const char *var_value, int flags );
void trap_Cvar_InfoStringBuffer( int bit, char *buffer, int bufsize );
-int trap_Argc( void );
+int trap_Argc( void );
void trap_Argv( int n, char *buffer, int bufferLength );
void trap_Cmd_ExecuteText( int exec_when, const char *text ); // don't use EXEC_NOW!
-int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
+int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
void trap_FS_Read( void *buffer, int len, fileHandle_t f );
void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
void trap_FS_FCloseFile( fileHandle_t f );
-int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
+int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
int trap_FS_Seek( fileHandle_t f, long offset, int origin ); // fsOrigin_t
-qhandle_t trap_R_RegisterModel( const char *name );
-qhandle_t trap_R_RegisterSkin( const char *name );
-qhandle_t trap_R_RegisterShaderNoMip( const char *name );
+qhandle_t trap_R_RegisterModel( const char *name );
+qhandle_t trap_R_RegisterSkin( const char *name );
+qhandle_t trap_R_RegisterShaderNoMip( const char *name );
void trap_R_ClearScene( void );
void trap_R_AddRefEntityToScene( const refEntity_t *re );
void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts );
@@ -347,51 +348,51 @@ void trap_R_SetClipRegion( const float *region );
void trap_R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader );
void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs );
void trap_UpdateScreen( void );
-int trap_CM_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName );
+int trap_CM_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName );
void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum );
sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed );
void trap_Key_KeynumToStringBuf( int keynum, char *buf, int buflen );
void trap_Key_GetBindingBuf( int keynum, char *buf, int buflen );
void trap_Key_SetBinding( int keynum, const char *binding );
-qboolean trap_Key_IsDown( int keynum );
-qboolean trap_Key_GetOverstrikeMode( void );
+qboolean trap_Key_IsDown( int keynum );
+qboolean trap_Key_GetOverstrikeMode( void );
void trap_Key_SetOverstrikeMode( qboolean state );
void trap_Key_ClearStates( void );
-int trap_Key_GetCatcher( void );
+int trap_Key_GetCatcher( void );
void trap_Key_SetCatcher( int catcher );
void trap_GetClipboardData( char *buf, int bufsize );
void trap_GetClientState( uiClientState_t *state );
void trap_GetGlconfig( glconfig_t *glconfig );
-int trap_GetConfigString( int index, char* buff, int buffsize );
-int trap_LAN_GetServerCount( int source );
+int trap_GetConfigString( int index, char* buff, int buffsize );
+int trap_LAN_GetServerCount( int source );
void trap_LAN_GetServerAddressString( int source, int n, char *buf, int buflen );
void trap_LAN_GetServerInfo( int source, int n, char *buf, int buflen );
-int trap_LAN_GetServerPing( int source, int n );
-int trap_LAN_GetPingQueueCount( void );
+int trap_LAN_GetServerPing( int source, int n );
+int trap_LAN_GetPingQueueCount( void );
void trap_LAN_ClearPing( int n );
void trap_LAN_GetPing( int n, char *buf, int buflen, int *pingtime );
void trap_LAN_GetPingInfo( int n, char *buf, int buflen );
void trap_LAN_LoadCachedServers( void );
void trap_LAN_SaveCachedServers( void );
void trap_LAN_MarkServerVisible( int source, int n, qboolean visible );
-int trap_LAN_ServerIsVisible( int source, int n );
-qboolean trap_LAN_UpdateVisiblePings( int source );
-int trap_LAN_AddServer( int source, const char *name, const char *addr );
+int trap_LAN_ServerIsVisible( int source, int n );
+qboolean trap_LAN_UpdateVisiblePings( int source );
+int trap_LAN_AddServer( int source, const char *name, const char *addr );
void trap_LAN_RemoveServer( int source, const char *addr );
void trap_LAN_ResetPings( int n );
-int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen );
-qboolean trap_GetNews( qboolean force );
-int trap_LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 );
-int trap_MemoryRemaining( void );
+int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen );
+qboolean trap_GetNews( qboolean force );
+int trap_LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 );
+int trap_MemoryRemaining( void );
void trap_R_RegisterFont( const char *pFontname, int pointSize, fontInfo_t *font );
void trap_S_StopBackgroundTrack( void );
void trap_S_StartBackgroundTrack( const char *intro, const char *loop );
-int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits );
-e_status trap_CIN_StopCinematic( int handle );
-e_status trap_CIN_RunCinematic ( int handle );
+int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits );
+e_status trap_CIN_StopCinematic( int handle );
+e_status trap_CIN_RunCinematic ( int handle );
void trap_CIN_DrawCinematic ( int handle );
void trap_CIN_SetExtents ( int handle, int x, int y, int w, int h );
-int trap_RealTime( qtime_t *qtime );
+int trap_RealTime( qtime_t *qtime );
void trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset );
void trap_SetPbClStatus( int status );
diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c
index 46961723..9dd52c18 100644
--- a/src/ui/ui_main.c
+++ b/src/ui/ui_main.c
@@ -235,10 +235,14 @@ void AssetCache( void )
void UI_DrawSides( float x, float y, float w, float h, float size )
{
+ float sizeY;
+
UI_AdjustFrom640( &x, &y, &w, &h );
+ sizeY = size * uiInfo.uiDC.yscale;
size *= uiInfo.uiDC.xscale;
- trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
- trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
+
+ trap_R_DrawStretchPic( x, y + sizeY, size, h - ( sizeY * 2.0f ), 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
+ trap_R_DrawStretchPic( x + w - size, y + sizeY, size, h - ( sizeY * 2.0f ), 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
}
void UI_DrawTopBottom( float x, float y, float w, float h, float size )
@@ -633,7 +637,7 @@ static char *stristr( char *str, char *charset )
UI_BuildFindPlayerList
==================
*/
-static void UI_FeederSelection( float feederID, int index );
+static void UI_FeederSelection( int feederID, int index );
static void UI_BuildFindPlayerList( qboolean force )
{
@@ -1172,15 +1176,11 @@ void UI_Refresh( int realtime )
if( Menu_Count() > 0 )
{
- // paint all the menus
- Menu_PaintAll();
- // refresh server browser list
- UI_DoServerRefresh();
- // refresh server status
+ Menu_UpdateAll( );
+ Menu_PaintAll( );
+ UI_DoServerRefresh( );
UI_BuildServerStatus( qfalse );
- // refresh find player list
UI_BuildFindPlayerList( qfalse );
- // refresh news
UI_UpdateNews( qfalse );
}
@@ -3416,12 +3416,14 @@ static void UI_RunMenuScript( char **args )
}
}
+static int UI_FeederInitialise( int feederID );
+
/*
==================
UI_FeederCount
==================
*/
-static int UI_FeederCount( float feederID )
+static int UI_FeederCount( int feederID )
{
if( feederID == FEEDER_CINEMATICS )
return uiInfo.movieCount;
@@ -3480,7 +3482,12 @@ static int UI_FeederCount( float feederID )
else if( feederID == FEEDER_TREMHUMANBUILD )
return uiInfo.humanBuildCount;
else if( feederID == FEEDER_RESOLUTIONS )
- return uiInfo.numResolutions;
+ {
+ if( UI_FeederInitialise( feederID ) == uiInfo.numResolutions )
+ return uiInfo.numResolutions + 1;
+ else
+ return uiInfo.numResolutions;
+ }
return 0;
}
@@ -3505,16 +3512,39 @@ static const char *UI_SelectedMap( int index, int *actual )
return "";
}
-static const char *UI_FeederItemText( float feederID, int index, int column, qhandle_t *handle )
+static int GCD( int a, int b )
{
- static char info[MAX_STRING_CHARS];
- static char hostname[1024];
- static char cleaned[1024];
- static char clientBuff[32];
- static char resolution[MAX_STRING_CHARS];
- static int lastColumn = -1;
- static int lastTime = 0;
+ int c;
+
+ while( b != 0 )
+ {
+ c = a % b;
+ a = b;
+ b = c;
+ }
+ return a;
+}
+
+static const char *UI_DisplayAspectString( int w, int h )
+{
+ int gcd = GCD( w, h );
+
+ w /= gcd;
+ h /= gcd;
+
+ // For some reason 8:5 is usually referred to as 16:10
+ if( w == 8 && h == 5 )
+ {
+ w = 16;
+ h = 10;
+ }
+
+ return va( "%d:%d", w, h );
+}
+
+static const char *UI_FeederItemText( int feederID, int index, int column, qhandle_t *handle )
+{
if( handle )
*handle = -1;
@@ -3527,7 +3557,12 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
{
if( index >= 0 && index < UI_FeederCount( feederID ) )
{
- int ping;
+ static char info[MAX_STRING_CHARS];
+ static char clientBuff[ 32 ];
+ static char cleaned[ MAX_STRING_CHARS ];
+ static int lastColumn = -1;
+ static int lastTime = 0;
+ int ping;
if( lastColumn != column || lastTime > uiInfo.uiDC.realTime + 5000 )
{
@@ -3539,12 +3574,6 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
ping = atoi( Info_ValueForKey( info, "ping" ) );
- if( ping == -1 )
- {
- // if we ever see a ping that is out of date, do a server refresh
- // UI_UpdatePendingPings();
- }
-
UI_EscapeEmoticons( cleaned, Info_ValueForKey( info, "hostname" ), sizeof( cleaned ) );
switch( column )
@@ -3554,10 +3583,11 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
return Info_ValueForKey( info, "addr" );
else
{
+ static char hostname[1024];
+
if( ui_netSource.integer == AS_LOCAL )
{
- Com_sprintf( hostname, sizeof( hostname ), "%s [%s]",
- cleaned,
+ Com_sprintf( hostname, sizeof( hostname ), "%s [%s]", cleaned,
netnames[atoi( Info_ValueForKey( info, "nettype" ) )] );
return hostname;
}
@@ -3573,13 +3603,12 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
label+= 1;
Com_sprintf( hostname, sizeof( hostname ), "%s %s",
- label,
- cleaned );
+ label, cleaned );
}
else
{
Com_sprintf( hostname, sizeof( hostname ), "%s",
- cleaned );
+ cleaned );
}
// Strip leading whitespace
@@ -3619,17 +3648,12 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
else if( feederID == FEEDER_NEWS )
{
if( index >= 0 && index < uiInfo.newsInfo.numLines )
- {
return uiInfo.newsInfo.text[index];
- }
}
else if( feederID == FEEDER_FINDPLAYER )
{
if( index >= 0 && index < uiInfo.numFoundPlayerServers )
- {
- //return uiInfo.foundPlayerServerAddresses[index];
return uiInfo.foundPlayerServerNames[index];
- }
}
else if( feederID == FEEDER_PLAYER_LIST )
{
@@ -3649,13 +3673,13 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
{
case 1:
// am I ignoring him
- return ( Com_ClientListContains( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ index ] ) ) ? "X" : "";
+ return Com_ClientListContains( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
+ uiInfo.clientNums[ index ] ) ? "X" : "";
case 2:
// is he ignoring me
- return ( Com_ClientListContains( &uiInfo.ignoreList[ index ],
- uiInfo.playerNumber ) ) ? "X" : "";
+ return Com_ClientListContains( &uiInfo.ignoreList[ index ],
+ uiInfo.playerNumber ) ? "X" : "";
default:
return uiInfo.playerNames[index];
@@ -3729,20 +3753,24 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
}
else if( feederID == FEEDER_RESOLUTIONS )
{
- int i;
- int w = trap_Cvar_VariableValue( "r_width" );
- int h = trap_Cvar_VariableValue( "r_height" );
+ static char resolution[MAX_STRING_CHARS];
+ int w, h;
- for( i = 0; i < uiInfo.numResolutions; i++ )
+ if( index >= 0 && index < uiInfo.numResolutions )
{
- if( w == uiInfo.resolutions[ i ].w && h == uiInfo.resolutions[ i ].h )
- {
- Com_sprintf( resolution, sizeof( resolution ), "%dx%d", w, h );
- return resolution;
- }
+ w = uiInfo.resolutions[ index ].w;
+ h = uiInfo.resolutions[ index ].h;
+
+ Com_sprintf( resolution, sizeof( resolution ), "%dx%d (%s)", w, h,
+ UI_DisplayAspectString( w, h ) );
+
+ return resolution;
}
+ w = (int)trap_Cvar_VariableValue( "r_width" );
+ h = (int)trap_Cvar_VariableValue( "r_height" );
Com_sprintf( resolution, sizeof( resolution ), "Custom (%dx%d)", w, h );
+
return resolution;
}
@@ -3750,7 +3778,7 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
}
-static qhandle_t UI_FeederItemImage( float feederID, int index )
+static qhandle_t UI_FeederItemImage( int feederID, int index )
{
if( feederID == FEEDER_MAPS )
{
@@ -3770,7 +3798,7 @@ static qhandle_t UI_FeederItemImage( float feederID, int index )
return 0;
}
-static void UI_FeederSelection( float feederID, int index )
+static void UI_FeederSelection( int feederID, int index )
{
static char info[MAX_STRING_CHARS];
@@ -3874,12 +3902,17 @@ static void UI_FeederSelection( float feederID, int index )
uiInfo.humanBuildIndex = index;
else if( feederID == FEEDER_RESOLUTIONS )
{
- trap_Cvar_Set( "r_width", va( "%d", uiInfo.resolutions[ index ].w ) );
- trap_Cvar_Set( "r_height", va( "%d", uiInfo.resolutions[ index ].h ) );
+ if( index >= 0 && index < uiInfo.numResolutions )
+ {
+ trap_Cvar_Set( "r_width", va( "%d", uiInfo.resolutions[ index ].w ) );
+ trap_Cvar_Set( "r_height", va( "%d", uiInfo.resolutions[ index ].h ) );
+ }
+
+ uiInfo.resolutionIndex = index;
}
}
-static int UI_FeederInitialise( float feederID )
+static int UI_FeederInitialise( int feederID )
{
if( feederID == FEEDER_RESOLUTIONS )
{
@@ -3892,6 +3925,8 @@ static int UI_FeederInitialise( float feederID )
if( w == uiInfo.resolutions[ i ].w && h == uiInfo.resolutions[ i ].h )
return i;
}
+
+ return uiInfo.numResolutions;
}
return 0;
@@ -4605,7 +4640,8 @@ void UI_UpdateNews( qboolean begin )
trap_Cvar_VariableStringBuffer( "cl_newsString", newsString,
sizeof( newsString ) );
- wrapped = Item_Text_Wrap( newsString, .25, 325 * uiInfo.uiDC.aspectScale );
+ // FIXME remove magic width constant
+ wrapped = Item_Text_Wrap( newsString, 0.25f, 325 * uiInfo.uiDC.aspectScale );
for( c = wrapped; *c != '\0'; ++c ) {
if( linePos == (MAX_NEWS_LINEWIDTH - 1) || *c == '\n' ) {
@@ -4632,6 +4668,5 @@ void UI_UpdateNews( qboolean begin )
if( finished )
uiInfo.newsInfo.refreshActive = qfalse;
-
}
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index 2e54df2b..2199a449 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -66,6 +66,7 @@ static qboolean g_editingField = qfalse;
static itemDef_t *g_bindItem = NULL;
static itemDef_t *g_editItem = NULL;
+static itemDef_t *g_comboBoxItem = NULL;
menuDef_t Menus[MAX_MENUS]; // defined menus
int menuCount = 0; // how many
@@ -79,6 +80,8 @@ static int lastListBoxClickTime = 0;
void Item_RunScript( itemDef_t *item, const char *s );
void Item_SetupKeywordHash( void );
static ID_INLINE qboolean Item_IsEditField( itemDef_t *item );
+static ID_INLINE qboolean Item_IsListBox( itemDef_t *item );
+static void Item_ListBox_SetStartPos( itemDef_t *item, int startPos );
void Menu_SetupKeywordHash( void );
int BindingIDFromName( const char *name );
qboolean Item_Bind_HandleKey( itemDef_t *item, int key, qboolean down );
@@ -430,7 +433,7 @@ exprList_t;
/*
=================
OpPrec
-
+
Return a value reflecting operator precedence
=================
*/
@@ -964,9 +967,8 @@ void GradientBar_Paint( rectDef_t *rect, vec4_t color )
/*
==================
Window_Init
-
+
Initializes a window structure ( windowDef_t ) with defaults
-
==================
*/
void Window_Init( Window *w )
@@ -1236,6 +1238,23 @@ void Menu_AspectCompensate( menuDef_t *menu )
}
}
+static int Menu_CompareItemTypes( const void *a, const void *b )
+{
+ itemDef_t *itemA = *(itemDef_t **)a;
+ itemDef_t *itemB = *(itemDef_t **)b;
+ qboolean itemAIsList = Item_IsListBox( itemA );
+ qboolean itemBIsList = Item_IsListBox( itemB );
+
+ if( itemAIsList && itemBIsList )
+ return 0;
+ else if( itemAIsList )
+ return 1;
+ else if( itemBIsList )
+ return -1;
+ else
+ return 0;
+}
+
void Menu_PostParse( menuDef_t *menu )
{
if( menu == NULL )
@@ -1251,6 +1270,11 @@ void Menu_PostParse( menuDef_t *menu )
Menu_AspectCompensate( menu );
Menu_UpdatePosition( menu );
+
+ // Sort lists to the end of the array as they can potentially be drawn on top
+ // of other elements
+ if( menu->itemCount > 1 )
+ qsort( menu->items, menu->itemCount, sizeof( itemDef_t* ), Menu_CompareItemTypes );
}
itemDef_t *Menu_ClearFocus( menuDef_t *menu )
@@ -1576,6 +1600,7 @@ void Menus_CloseAll( void )
g_editingField = qfalse;
g_waitingForKey = qfalse;
+ g_comboBoxItem = NULL;
}
@@ -1775,11 +1800,11 @@ void Script_Reset( itemDef_t *item, char **args )
if( resetItem )
{
- if( resetItem->type == ITEM_TYPE_LISTBOX )
+ if( Item_IsListBox( resetItem ) )
{
- resetItem->cursorPos = 0;
- resetItem->typeData.list->startPos = 0;
- DC->feederSelection( resetItem->feederID, 0 );
+ resetItem->cursorPos = DC->feederInitialise( resetItem->feederID );
+ Item_ListBox_SetStartPos( resetItem, 0 );
+ DC->feederSelection( resetItem->feederID, resetItem->cursorPos );
}
}
}
@@ -2067,7 +2092,7 @@ float UI_Text_EmHeight( float scale )
/*
================
UI_AdjustFrom640
-
+
Adjusted for resolution and screen aspect ratio
================
*/
@@ -2079,6 +2104,35 @@ void UI_AdjustFrom640( float *x, float *y, float *w, float *h )
*h *= DC->yscale;
}
+/*
+================
+UI_SetClipRegion
+=================
+*/
+void UI_SetClipRegion( float x, float y, float w, float h )
+{
+ vec4_t clip;
+
+ UI_AdjustFrom640( &x, &y, &w, &h );
+
+ clip[ 0 ] = x;
+ clip[ 1 ] = y;
+ clip[ 2 ] = x + w;
+ clip[ 3 ] = y + h;
+
+ trap_R_SetClipRegion( clip );
+}
+
+/*
+================
+UI_ClearClipRegion
+=================
+*/
+void UI_ClearClipRegion( void )
+{
+ trap_R_SetClipRegion( NULL );
+}
+
static void UI_Text_PaintChar( float x, float y, float scale,
glyphInfo_t *glyph, float size )
{
@@ -2290,19 +2344,19 @@ commandDef_t commandList[] =
{
{"close", &Script_Close}, // menu
{"conditionalopen", &Script_ConditionalOpen}, // menu
- {"exec", &Script_Exec}, // group/name
+ {"exec", &Script_Exec}, // group/name
{"fadein", &Script_FadeIn}, // group/name
{"fadeout", &Script_FadeOut}, // group/name
{"hide", &Script_Hide}, // group/name
{"open", &Script_Open}, // menu
{"orbit", &Script_Orbit}, // group/name
- {"play", &Script_Play}, // group/name
+ {"play", &Script_Play}, // group/name
{"playlooped", &Script_playLooped}, // group/name
{"reset", &Script_Reset}, // resets the state of the item argument
{"setasset", &Script_SetAsset}, // works on this
{"setbackground", &Script_SetBackground}, // works on this
{"setcolor", &Script_SetColor}, // works on this
- {"setcvar", &Script_SetCvar}, // group/name
+ {"setcvar", &Script_SetCvar}, // group/name
{"setfocus", &Script_SetFocus}, // sets this background color to team color
{"setitemcolor", &Script_SetItemColor}, // group/name
{"setplayerhead", &Script_SetPlayerHead}, // sets this background color to team color
@@ -2482,16 +2536,27 @@ qboolean Item_SetFocus( itemDef_t *item, float x, float y )
return qtrue;
}
-int Item_ListBox_MaxScroll( itemDef_t *item )
+static float Item_ListBox_HeightForNumItems( itemDef_t *item, int numItems )
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+
+ return ( listPtr->elementHeight * numItems ) + 2.0f;
+}
+
+static int Item_ListBox_NumItemsForItemHeight( itemDef_t *item )
{
listBoxDef_t *listPtr = item->typeData.list;
- int count = DC->feederCount( item->feederID );
- int max;
- if( item->window.flags & WINDOW_HORIZONTAL )
- max = count - ( item->window.rect.w / listPtr->elementWidth ) + 1;
+ if( item->type == ITEM_TYPE_COMBOBOX )
+ return listPtr->dropItems;
else
- max = count - ( item->window.rect.h / listPtr->elementHeight ) + 1;
+ return ( ( item->window.rect.h - 2.0f ) / listPtr->elementHeight );
+}
+
+int Item_ListBox_MaxScroll( itemDef_t *item )
+{
+ int total = DC->feederCount( item->feederID );
+ int max = total - Item_ListBox_NumItemsForItemHeight( item );
if( max < 0 )
return 0;
@@ -2499,68 +2564,86 @@ int Item_ListBox_MaxScroll( itemDef_t *item )
return max;
}
-int Item_ListBox_ThumbPosition( itemDef_t *item )
-{
- float max, pos, size;
- int startPos = item->typeData.list->startPos;
+static float oldComboBoxY;
+static float oldComboBoxH;
- max = Item_ListBox_MaxScroll( item );
+static qboolean Item_ComboBox_MaybeCastToListBox( itemDef_t *item )
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+ qboolean cast = g_comboBoxItem != NULL &&
+ ( item->type == ITEM_TYPE_COMBOBOX );
- if( item->window.flags & WINDOW_HORIZONTAL )
+ if( cast )
{
- size = item->window.rect.w - ( SCROLLBAR_WIDTH * 2 ) - 2;
-
- if( max > 0 )
- pos = ( size - SCROLLBAR_WIDTH ) / ( float ) max;
- else
- pos = 0;
+ oldComboBoxY = item->window.rect.y;
+ oldComboBoxH = item->window.rect.h;
- pos *= startPos;
- return item->window.rect.x + 1 + SCROLLBAR_WIDTH + pos;
+ item->window.rect.y += item->window.rect.h;
+ item->window.rect.h = Item_ListBox_HeightForNumItems( item, listPtr->dropItems );
+ item->type = ITEM_TYPE_LISTBOX;
}
- else
- {
- size = item->window.rect.h - ( SCROLLBAR_HEIGHT * 2 ) - 2;
- if( max > 0 )
- pos = ( size - SCROLLBAR_HEIGHT ) / ( float ) max;
- else
- pos = 0;
+ return cast;
+}
- pos *= startPos;
- return item->window.rect.y + 1 + SCROLLBAR_HEIGHT + pos;
+static void Item_ComboBox_MaybeUnCastFromListBox( itemDef_t *item, qboolean unCast )
+{
+ if( unCast )
+ {
+ item->window.rect.y = oldComboBoxY;
+ item->window.rect.h = oldComboBoxH;
+ item->type = ITEM_TYPE_COMBOBOX;
}
}
-int Item_ListBox_ThumbDrawPosition( itemDef_t *item )
+static void Item_ListBox_SetStartPos( itemDef_t *item, int startPos )
{
- int min, max;
+ listBoxDef_t *listPtr = item->typeData.list;
+ int total = DC->feederCount( item->feederID );
+ int max = Item_ListBox_MaxScroll( item );
+
+ if( startPos < 0 )
+ listPtr->startPos = 0;
+ else if( startPos > max )
+ listPtr->startPos = max;
+ else
+ listPtr->startPos = startPos;
+
+ listPtr->endPos = listPtr->startPos + MIN( ( total - listPtr->startPos ),
+ Item_ListBox_NumItemsForItemHeight( item ) );
+}
+float Item_ListBox_ThumbPosition( itemDef_t *item )
+{
+ float max, pos, size;
+ float startPos = (float)item->typeData.list->startPos;
+
+ max = Item_ListBox_MaxScroll( item );
+ size = SCROLLBAR_SLIDER_HEIGHT( item );
+
+ if( max > 0.0f )
+ pos = ( size - SCROLLBAR_ARROW_HEIGHT ) / max;
+ else
+ pos = 0.0f;
+
+ pos *= startPos;
+
+ return SCROLLBAR_SLIDER_Y( item ) + pos;
+}
+
+float Item_ListBox_ThumbDrawPosition( itemDef_t *item )
+{
if( itemCapture == item )
{
- if( item->window.flags & WINDOW_HORIZONTAL )
- {
- min = item->window.rect.x + SCROLLBAR_WIDTH + 1;
- max = item->window.rect.x + item->window.rect.w - 2 * SCROLLBAR_WIDTH - 1;
-
- if( DC->cursorx >= min + SCROLLBAR_WIDTH / 2 && DC->cursorx <= max + SCROLLBAR_WIDTH / 2 )
- return DC->cursorx - SCROLLBAR_WIDTH / 2;
- else
- return Item_ListBox_ThumbPosition( item );
- }
- else
- {
- min = item->window.rect.y + SCROLLBAR_HEIGHT + 1;
- max = item->window.rect.y + item->window.rect.h - 2 * SCROLLBAR_HEIGHT - 1;
+ float min = SCROLLBAR_SLIDER_Y( item );
+ float max = min + SCROLLBAR_SLIDER_HEIGHT( item ) - SCROLLBAR_ARROW_HEIGHT;
+ float halfThumbSize = SCROLLBAR_ARROW_HEIGHT / 2.0f;
- if( DC->cursory >= min + SCROLLBAR_HEIGHT / 2 && DC->cursory <= max + SCROLLBAR_HEIGHT / 2 )
- return DC->cursory - SCROLLBAR_HEIGHT / 2;
- else
- return Item_ListBox_ThumbPosition( item );
- }
+ if( DC->cursory >= min + halfThumbSize && DC->cursory <= max + halfThumbSize )
+ return DC->cursory - halfThumbSize;
}
- else
- return Item_ListBox_ThumbPosition( item );
+
+ return Item_ListBox_ThumbPosition( item );
}
float Item_Slider_ThumbPosition( itemDef_t *item )
@@ -2625,76 +2708,36 @@ int Item_ListBox_OverLB( itemDef_t *item, float x, float y )
count = DC->feederCount( item->feederID );
- if( item->window.flags & WINDOW_HORIZONTAL )
- {
- // check if on left arrow
- r.x = item->window.rect.x;
- r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_HEIGHT;
- r.w = SCROLLBAR_WIDTH;
- r.h = SCROLLBAR_HEIGHT;
-
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_LEFTARROW;
-
- // check if on right arrow
- r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_WIDTH;
+ r.x = SCROLLBAR_SLIDER_X( item );
+ r.y = SCROLLBAR_Y( item );
+ r.w = SCROLLBAR_ARROW_WIDTH;
+ r.h = SCROLLBAR_ARROW_HEIGHT;
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_RIGHTARROW;
-
- // check if on thumb
- thumbstart = Item_ListBox_ThumbPosition( item );
-
- r.x = thumbstart;
-
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_THUMB;
-
- r.x = item->window.rect.x + SCROLLBAR_WIDTH;
- r.w = thumbstart - r.x;
-
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_PGUP;
-
- r.x = thumbstart + SCROLLBAR_WIDTH;
- r.w = item->window.rect.x + item->window.rect.w - SCROLLBAR_WIDTH;
-
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_PGDN;
- }
- else
- {
- r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_WIDTH;
- r.y = item->window.rect.y;
- r.w = SCROLLBAR_WIDTH;
- r.h = SCROLLBAR_HEIGHT;
-
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_LEFTARROW;
+ if( Rect_ContainsPoint( &r, x, y ) )
+ return WINDOW_LB_UPARROW;
- r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_HEIGHT;
+ r.y = SCROLLBAR_SLIDER_Y( item ) + SCROLLBAR_SLIDER_HEIGHT( item );
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_RIGHTARROW;
+ if( Rect_ContainsPoint( &r, x, y ) )
+ return WINDOW_LB_DOWNARROW;
- thumbstart = Item_ListBox_ThumbPosition( item );
- r.y = thumbstart;
+ thumbstart = Item_ListBox_ThumbPosition( item );
+ r.y = thumbstart;
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_THUMB;
+ if( Rect_ContainsPoint( &r, x, y ) )
+ return WINDOW_LB_THUMB;
- r.y = item->window.rect.y + SCROLLBAR_HEIGHT;
- r.h = thumbstart - r.y;
+ r.y = SCROLLBAR_SLIDER_Y( item );
+ r.h = thumbstart - r.y;
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_PGUP;
+ if( Rect_ContainsPoint( &r, x, y ) )
+ return WINDOW_LB_PGUP;
- r.y = thumbstart + SCROLLBAR_HEIGHT;
- r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_HEIGHT;
+ r.y = thumbstart + SCROLLBAR_ARROW_HEIGHT;
+ r.h = ( SCROLLBAR_SLIDER_Y( item ) + SCROLLBAR_SLIDER_HEIGHT( item ) ) - r.y;
- if( Rect_ContainsPoint( &r, x, y ) )
- return WINDOW_LB_PGDN;
- }
+ if( Rect_ContainsPoint( &r, x, y ) )
+ return WINDOW_LB_PGDN;
return 0;
}
@@ -2702,52 +2745,32 @@ int Item_ListBox_OverLB( itemDef_t *item, float x, float y )
void Item_ListBox_MouseEnter( itemDef_t *item, float x, float y )
{
- rectDef_t r;
- listBoxDef_t *listPtr = item->typeData.list;
+ rectDef_t r;
+ listBoxDef_t *listPtr = item->typeData.list;
+ int listBoxFlags = ( WINDOW_LB_UPARROW | WINDOW_LB_DOWNARROW | WINDOW_LB_THUMB |
+ WINDOW_LB_PGUP | WINDOW_LB_PGDN );
+ int total = DC->feederCount( item->feederID );
- item->window.flags &= ~( WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB |
- WINDOW_LB_PGUP | WINDOW_LB_PGDN );
+ item->window.flags &= ~listBoxFlags;
item->window.flags |= Item_ListBox_OverLB( item, x, y );
- if( item->window.flags & WINDOW_HORIZONTAL )
- {
- if( !( item->window.flags & ( WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB |
- WINDOW_LB_PGUP | WINDOW_LB_PGDN ) ) )
- {
- // check for selection hit as we have exausted buttons and thumb
-
- if( listPtr->elementStyle == LISTBOX_IMAGE )
- {
- r.x = item->window.rect.x;
- r.y = item->window.rect.y;
- r.h = item->window.rect.h - SCROLLBAR_HEIGHT;
- r.w = item->window.rect.w - listPtr->drawPadding;
-
- if( Rect_ContainsPoint( &r, x, y ) )
- {
- listPtr->cursorPos = ( int )( ( x - r.x ) / listPtr->elementWidth ) + listPtr->startPos;
-
- if( listPtr->cursorPos >= listPtr->endPos )
- listPtr->cursorPos = listPtr->endPos;
- }
- }
- }
- }
- else if( !( item->window.flags & ( WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW |
- WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN ) ) )
+ if( !( item->window.flags & listBoxFlags ) )
{
- r.x = item->window.rect.x;
- r.y = item->window.rect.y;
- r.w = item->window.rect.w - SCROLLBAR_WIDTH;
- r.h = item->window.rect.h - listPtr->drawPadding;
+ r.x = SCROLLBAR_X( item );
+ r.y = SCROLLBAR_Y( item );
+ r.w = SCROLLBAR_W( item );
+ r.h = listPtr->elementHeight *
+ MIN( Item_ListBox_NumItemsForItemHeight( item ), total );
if( Rect_ContainsPoint( &r, x, y ) )
{
- listPtr->cursorPos = ( int )( ( y - 2 - r.y ) / listPtr->elementHeight ) + listPtr->startPos;
+ listPtr->cursorPos = (int)( ( y - r.y ) / listPtr->elementHeight ) + listPtr->startPos;
- if( listPtr->cursorPos > listPtr->endPos )
- listPtr->cursorPos = listPtr->endPos;
+ if( listPtr->cursorPos >= listPtr->endPos )
+ listPtr->cursorPos = listPtr->endPos - 1;
}
+ else
+ listPtr->cursorPos = -1;
}
}
@@ -2818,7 +2841,7 @@ void Item_MouseLeave( itemDef_t *item )
}
Item_RunScript( item, item->mouseExit );
- item->window.flags &= ~( WINDOW_LB_RIGHTARROW | WINDOW_LB_LEFTARROW );
+ item->window.flags &= ~( WINDOW_LB_DOWNARROW | WINDOW_LB_UPARROW );
}
}
@@ -2859,299 +2882,158 @@ qboolean Item_ListBox_HandleKey( itemDef_t *item, int key, qboolean down, qboole
{
listBoxDef_t *listPtr = item->typeData.list;
int count = DC->feederCount( item->feederID );
- int max, viewmax;
+ int viewmax;
if( force || ( Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) &&
item->window.flags & WINDOW_HASFOCUS ) )
{
- max = Item_ListBox_MaxScroll( item );
+ viewmax = Item_ListBox_NumItemsForItemHeight( item );
- if( item->window.flags & WINDOW_HORIZONTAL )
+ switch( key )
{
- viewmax = ( item->window.rect.w / listPtr->elementWidth );
-
- if( key == K_LEFTARROW || key == K_KP_LEFTARROW )
- {
- if( !listPtr->notselectable )
+ case K_MOUSE1:
+ case K_MOUSE2:
+ if( item->window.flags & WINDOW_LB_UPARROW )
+ Item_ListBox_SetStartPos( item, listPtr->startPos - 1 );
+ else if( item->window.flags & WINDOW_LB_DOWNARROW )
+ Item_ListBox_SetStartPos( item, listPtr->startPos + 1 );
+ else if( item->window.flags & WINDOW_LB_PGUP )
+ Item_ListBox_SetStartPos( item, listPtr->startPos - viewmax );
+ else if( item->window.flags & WINDOW_LB_PGDN )
+ Item_ListBox_SetStartPos( item, listPtr->startPos + viewmax );
+ else if( item->window.flags & WINDOW_LB_THUMB )
+ break; // Handled by capture function
+ else
{
- listPtr->cursorPos--;
+ // Select an item
+ qboolean runDoubleClick = qfalse;
+ // Mouse isn't over an item
if( listPtr->cursorPos < 0 )
- listPtr->cursorPos = 0;
-
- if( listPtr->cursorPos < listPtr->startPos )
- listPtr->startPos = listPtr->cursorPos;
-
- if( listPtr->cursorPos >= listPtr->startPos + viewmax )
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
+ break;
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection( item->feederID, item->cursorPos );
- }
- else
- {
- listPtr->startPos--;
+ if( item->cursorPos != listPtr->cursorPos )
+ {
+ item->cursorPos = listPtr->cursorPos;
+ DC->feederSelection( item->feederID, item->cursorPos );
+ }
- if( listPtr->startPos < 0 )
- listPtr->startPos = 0;
- }
+ runDoubleClick = DC->realTime < lastListBoxClickTime && listPtr->doubleClick;
+ lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY;
- return qtrue;
- }
+ // Made a selection, so close combobox
+ if( g_comboBoxItem != NULL )
+ {
+ if( listPtr->doubleClick )
+ runDoubleClick = qtrue;
- if( key == K_RIGHTARROW || key == K_KP_RIGHTARROW )
- {
- if( !listPtr->notselectable )
- {
- listPtr->cursorPos++;
+ g_comboBoxItem = NULL;
+ }
- if( listPtr->cursorPos < listPtr->startPos )
- listPtr->startPos = listPtr->cursorPos;
+ if( runDoubleClick )
+ Item_RunScript( item, listPtr->doubleClick );
+ }
- if( listPtr->cursorPos >= count )
- listPtr->cursorPos = count - 1;
+ break;
- if( listPtr->cursorPos >= listPtr->startPos + viewmax )
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
+ case K_MWHEELUP:
+ Item_ListBox_SetStartPos( item, listPtr->startPos - 1 );
+ break;
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection( item->feederID, item->cursorPos );
- }
- else
- {
- listPtr->startPos++;
+ case K_MWHEELDOWN:
+ Item_ListBox_SetStartPos( item, listPtr->startPos + 1 );
+ break;
- if( listPtr->startPos >= count )
- listPtr->startPos = count - 1;
- }
+ case K_ENTER:
+ // Invoke the doubleClick handler when enter is pressed
+ if( listPtr->doubleClick )
+ Item_RunScript( item, listPtr->doubleClick );
- return qtrue;
- }
- }
- else
- {
- viewmax = ( item->window.rect.h / listPtr->elementHeight );
+ break;
- if( key == K_UPARROW || key == K_KP_UPARROW )
- {
+ case K_PGUP:
+ case K_KP_PGUP:
if( !listPtr->notselectable )
{
- listPtr->cursorPos--;
+ listPtr->cursorPos -= viewmax;
if( listPtr->cursorPos < 0 )
listPtr->cursorPos = 0;
if( listPtr->cursorPos < listPtr->startPos )
- listPtr->startPos = listPtr->cursorPos;
+ Item_ListBox_SetStartPos( item, listPtr->cursorPos );
if( listPtr->cursorPos >= listPtr->startPos + viewmax )
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
+ Item_ListBox_SetStartPos( item, listPtr->cursorPos - viewmax + 1 );
item->cursorPos = listPtr->cursorPos;
DC->feederSelection( item->feederID, item->cursorPos );
}
else
- {
- listPtr->startPos--;
-
- if( listPtr->startPos < 0 )
- listPtr->startPos = 0;
- }
+ Item_ListBox_SetStartPos( item, listPtr->startPos - viewmax );
- return qtrue;
- }
+ break;
- if( key == K_DOWNARROW || key == K_KP_DOWNARROW )
- {
+ case K_PGDN:
+ case K_KP_PGDN:
if( !listPtr->notselectable )
{
- listPtr->cursorPos++;
+ listPtr->cursorPos += viewmax;
if( listPtr->cursorPos < listPtr->startPos )
- listPtr->startPos = listPtr->cursorPos;
+ Item_ListBox_SetStartPos( item, listPtr->cursorPos );
if( listPtr->cursorPos >= count )
listPtr->cursorPos = count - 1;
if( listPtr->cursorPos >= listPtr->startPos + viewmax )
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
+ Item_ListBox_SetStartPos( item, listPtr->cursorPos - viewmax + 1 );
item->cursorPos = listPtr->cursorPos;
DC->feederSelection( item->feederID, item->cursorPos );
}
else
- {
- listPtr->startPos++;
-
- if( listPtr->startPos > max )
- listPtr->startPos = max;
- }
-
- return qtrue;
- }
- }
+ Item_ListBox_SetStartPos( item, listPtr->startPos + viewmax );
- // mouse hit
- if( key == K_MOUSE1 || key == K_MOUSE2 )
- {
- if( item->window.flags & WINDOW_LB_LEFTARROW )
- {
- listPtr->startPos--;
-
- if( listPtr->startPos < 0 )
- listPtr->startPos = 0;
- }
- else if( item->window.flags & WINDOW_LB_RIGHTARROW )
- {
- // one down
- listPtr->startPos++;
-
- if( listPtr->startPos > max )
- listPtr->startPos = max;
- }
- else if( item->window.flags & WINDOW_LB_PGUP )
- {
- // page up
- listPtr->startPos -= viewmax;
-
- if( listPtr->startPos < 0 )
- listPtr->startPos = 0;
- }
- else if( item->window.flags & WINDOW_LB_PGDN )
- {
- // page down
- listPtr->startPos += viewmax;
-
- if( listPtr->startPos > max )
- listPtr->startPos = max;
- }
- else if( item->window.flags & WINDOW_LB_THUMB )
- {
- // Display_SetCaptureItem(item);
- }
- else
- {
- // select an item
-
- if( item->cursorPos != listPtr->cursorPos )
- {
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection( item->feederID, item->cursorPos );
- }
-
- if( DC->realTime < lastListBoxClickTime && listPtr->doubleClick )
- Item_RunScript( item, listPtr->doubleClick );
-
- lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY;
- }
-
- return qtrue;
- }
-
- // Scroll wheel
- if( key == K_MWHEELUP )
- {
- listPtr->startPos--;
-
- if( listPtr->startPos < 0 )
- listPtr->startPos = 0;
-
- return qtrue;
- }
-
- if( key == K_MWHEELDOWN )
- {
- listPtr->startPos++;
-
- if( listPtr->startPos > max )
- listPtr->startPos = max;
-
- return qtrue;
- }
-
- // Invoke the doubleClick handler when enter is pressed
- if( key == K_ENTER )
- {
- if( listPtr->doubleClick )
- Item_RunScript( item, listPtr->doubleClick );
-
- return qtrue;
- }
-
- if( key == K_HOME || key == K_KP_HOME )
- {
- // home
- listPtr->startPos = 0;
- return qtrue;
- }
+ break;
- if( key == K_END || key == K_KP_END )
- {
- // end
- listPtr->startPos = max;
- return qtrue;
+ default:
+ // Not handled
+ return qfalse;
}
- if( key == K_PGUP || key == K_KP_PGUP )
- {
- // page up
-
- if( !listPtr->notselectable )
- {
- listPtr->cursorPos -= viewmax;
-
- if( listPtr->cursorPos < 0 )
- listPtr->cursorPos = 0;
-
- if( listPtr->cursorPos < listPtr->startPos )
- listPtr->startPos = listPtr->cursorPos;
+ return qtrue;
+ }
- if( listPtr->cursorPos >= listPtr->startPos + viewmax )
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
+ return qfalse;
+}
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection( item->feederID, item->cursorPos );
- }
- else
- {
- listPtr->startPos -= viewmax;
+qboolean Item_ComboBox_HandleKey( itemDef_t *item, int key, qboolean down, qboolean force )
+{
+ if( g_comboBoxItem != NULL )
+ {
+ qboolean result;
- if( listPtr->startPos < 0 )
- listPtr->startPos = 0;
- }
+ qboolean cast = Item_ComboBox_MaybeCastToListBox( item );
+ result = Item_ListBox_HandleKey( item, key, down, force );
+ Item_ComboBox_MaybeUnCastFromListBox( item, cast );
- return qtrue;
- }
+ if( !result )
+ g_comboBoxItem = NULL;
- if( key == K_PGDN || key == K_KP_PGDN )
+ return result;
+ }
+ else
+ {
+ if( force || ( Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory ) &&
+ item->window.flags & WINDOW_HASFOCUS ) )
{
- // page down
-
- if( !listPtr->notselectable )
- {
- listPtr->cursorPos += viewmax;
-
- if( listPtr->cursorPos < listPtr->startPos )
- listPtr->startPos = listPtr->cursorPos;
-
- if( listPtr->cursorPos >= count )
- listPtr->cursorPos = count - 1;
-
- if( listPtr->cursorPos >= listPtr->startPos + viewmax )
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
-
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection( item->feederID, item->cursorPos );
- }
- else
+ if( key == K_MOUSE1 || key == K_MOUSE2 )
{
- listPtr->startPos += viewmax;
+ g_comboBoxItem = item;
- if( listPtr->startPos > max )
- listPtr->startPos = max;
+ return qtrue;
}
-
- return qtrue;
}
}
@@ -3246,13 +3128,13 @@ const char *Item_Multi_Setting( itemDef_t *item )
return "";
}
-qboolean Item_Combobox_HandleKey( itemDef_t *item, int key )
+qboolean Item_Cycle_HandleKey( itemDef_t *item, int key )
{
- comboBoxDef_t *comboPtr = item->typeData.combo;
+ cycleDef_t *cyclePtr = item->typeData.cycle;
qboolean mouseOver = Rect_ContainsPoint( &item->window.rect, DC->cursorx, DC->cursory );
int count = DC->feederCount( item->feederID );
- if( comboPtr )
+ if( cyclePtr )
{
if( item->window.flags & WINDOW_HASFOCUS )
{
@@ -3260,9 +3142,9 @@ qboolean Item_Combobox_HandleKey( itemDef_t *item, int key )
key == K_ENTER || key == K_RIGHTARROW || key == K_DOWNARROW )
{
if( count > 0 )
- comboPtr->cursorPos = ( comboPtr->cursorPos + 1 ) % count;
+ cyclePtr->cursorPos = ( cyclePtr->cursorPos + 1 ) % count;
- DC->feederSelection( item->feederID, comboPtr->cursorPos );
+ DC->feederSelection( item->feederID, cyclePtr->cursorPos );
return qtrue;
}
@@ -3270,9 +3152,9 @@ qboolean Item_Combobox_HandleKey( itemDef_t *item, int key )
key == K_LEFTARROW || key == K_UPARROW )
{
if( count > 0 )
- comboPtr->cursorPos = ( count + comboPtr->cursorPos - 1 ) % count;
+ cyclePtr->cursorPos = ( count + cyclePtr->cursorPos - 1 ) % count;
- DC->feederSelection( item->feederID, comboPtr->cursorPos );
+ DC->feederSelection( item->feederID, cyclePtr->cursorPos );
return qtrue;
}
@@ -3541,16 +3423,15 @@ exit:
return !releaseFocus;
}
-static void Scroll_ListBox_AutoFunc( void *p )
+static void _Scroll_ListBox_AutoFunc( scrollInfo_t *si )
{
- scrollInfo_t *si = ( scrollInfo_t* )p;
-
if( DC->realTime > si->nextScrollTime )
{
// need to scroll which is done by simulating a click to the item
// this is done a bit sideways as the autoscroll "knows" that the item is a listbox
// so it calls it directly
Item_ListBox_HandleKey( si->item, si->scrollKey, qtrue, qfalse );
+
si->nextScrollTime = DC->realTime + si->adjustValue;
}
@@ -3563,49 +3444,36 @@ static void Scroll_ListBox_AutoFunc( void *p )
}
}
-static void Scroll_ListBox_ThumbFunc( void *p )
+static void Scroll_ListBox_AutoFunc( void *p )
{
scrollInfo_t *si = ( scrollInfo_t* )p;
- rectDef_t r;
- int pos, max;
-
- if( si->item->window.flags & WINDOW_HORIZONTAL )
- {
- if( DC->cursorx == si->xStart )
- return;
- r.x = si->item->window.rect.x + SCROLLBAR_WIDTH + 1;
- r.y = si->item->window.rect.y + si->item->window.rect.h - SCROLLBAR_HEIGHT - 1;
- r.w = si->item->window.rect.w - ( SCROLLBAR_WIDTH * 2 ) - 2;
- r.h = SCROLLBAR_HEIGHT;
- max = Item_ListBox_MaxScroll( si->item );
- //
- pos = ( DC->cursorx - r.x - SCROLLBAR_WIDTH / 2 ) * max / ( r.w - SCROLLBAR_WIDTH );
+ qboolean cast = Item_ComboBox_MaybeCastToListBox( si->item );
+ _Scroll_ListBox_AutoFunc( si );
+ Item_ComboBox_MaybeUnCastFromListBox( si->item, cast );
+}
- if( pos < 0 )
- pos = 0;
- else if( pos > max )
- pos = max;
+static void _Scroll_ListBox_ThumbFunc( scrollInfo_t *si )
+{
+ rectDef_t r;
+ int pos, max;
- si->item->typeData.list->startPos = pos;
- si->xStart = DC->cursorx;
- }
- else if( DC->cursory != si->yStart )
+ if( DC->cursory != si->yStart )
{
- r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_WIDTH - 1;
- r.y = si->item->window.rect.y + SCROLLBAR_HEIGHT + 1;
- r.w = SCROLLBAR_WIDTH;
- r.h = si->item->window.rect.h - ( SCROLLBAR_HEIGHT * 2 ) - 2;
+ r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_ARROW_WIDTH - 1;
+ r.y = si->item->window.rect.y + SCROLLBAR_ARROW_HEIGHT + 1;
+ r.w = SCROLLBAR_ARROW_WIDTH;
+ r.h = si->item->window.rect.h - ( SCROLLBAR_ARROW_HEIGHT * 2 ) - 2;
max = Item_ListBox_MaxScroll( si->item );
//
- pos = ( DC->cursory - r.y - SCROLLBAR_HEIGHT / 2 ) * max / ( r.h - SCROLLBAR_HEIGHT );
+ pos = ( DC->cursory - r.y - SCROLLBAR_ARROW_HEIGHT / 2 ) * max / ( r.h - SCROLLBAR_ARROW_HEIGHT );
if( pos < 0 )
pos = 0;
else if( pos > max )
pos = max;
- si->item->typeData.list->startPos = pos;
+ Item_ListBox_SetStartPos( si->item, pos );
si->yStart = DC->cursory;
}
@@ -3615,6 +3483,7 @@ static void Scroll_ListBox_ThumbFunc( void *p )
// this is done a bit sideways as the autoscroll "knows" that the item is a listbox
// so it calls it directly
Item_ListBox_HandleKey( si->item, si->scrollKey, qtrue, qfalse );
+
si->nextScrollTime = DC->realTime + si->adjustValue;
}
@@ -3627,6 +3496,15 @@ static void Scroll_ListBox_ThumbFunc( void *p )
}
}
+static void Scroll_ListBox_ThumbFunc( void *p )
+{
+ scrollInfo_t *si = ( scrollInfo_t* )p;
+
+ qboolean cast = Item_ComboBox_MaybeCastToListBox( si->item );
+ _Scroll_ListBox_ThumbFunc( si );
+ Item_ComboBox_MaybeUnCastFromListBox( si->item, cast );
+}
+
static void Scroll_Slider_ThumbFunc( void *p )
{
float x, value, cursorx;
@@ -3662,20 +3540,20 @@ void Item_StartCapture( itemDef_t *item, int key )
switch( item->type )
{
- case ITEM_TYPE_EDITFIELD:
- case ITEM_TYPE_SAYFIELD:
- case ITEM_TYPE_NUMERICFIELD:
case ITEM_TYPE_LISTBOX:
+ case ITEM_TYPE_COMBOBOX:
{
+ qboolean cast = Item_ComboBox_MaybeCastToListBox( item );
flags = Item_ListBox_OverLB( item, DC->cursorx, DC->cursory );
+ Item_ComboBox_MaybeUnCastFromListBox( item, cast );
- if( flags & ( WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW ) )
+ if( flags & ( WINDOW_LB_UPARROW | WINDOW_LB_DOWNARROW ) )
{
scrollInfo.nextScrollTime = DC->realTime + SCROLL_TIME_START;
scrollInfo.nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
scrollInfo.adjustValue = SCROLL_TIME_START;
scrollInfo.scrollKey = key;
- scrollInfo.scrollDir = ( flags & WINDOW_LB_LEFTARROW ) ? qtrue : qfalse;
+ scrollInfo.scrollDir = ( flags & WINDOW_LB_UPARROW ) ? qtrue : qfalse;
scrollInfo.item = item;
UI_InstallCaptureFunc( Scroll_ListBox_AutoFunc, &scrollInfo, 0 );
itemCapture = item;
@@ -3786,12 +3664,15 @@ qboolean Item_HandleKey( itemDef_t *item, int key, qboolean down )
case ITEM_TYPE_CHECKBOX:
return qfalse;
- case ITEM_TYPE_COMBO:
- return Item_Combobox_HandleKey( item, key );
+ case ITEM_TYPE_CYCLE:
+ return Item_Cycle_HandleKey( item, key );
case ITEM_TYPE_LISTBOX:
return Item_ListBox_HandleKey( item, key, down, qfalse );
+ case ITEM_TYPE_COMBOBOX:
+ return Item_ComboBox_HandleKey( item, key, down, qfalse );
+
case ITEM_TYPE_YESNO:
return Item_YesNo_HandleKey( item, key );
@@ -3921,7 +3802,7 @@ static void Display_CloseCinematics( void )
Menu_CloseCinematics( &Menus[i] );
}
-void Menus_Activate( menuDef_t *menu )
+void Menus_Activate( menuDef_t *menu )
{
int i;
qboolean onTopOfMenuStack = qfalse;
@@ -3950,15 +3831,15 @@ void Menus_Activate( menuDef_t *menu )
for( i = 0; i < menu->itemCount; i++ ) // reset selection in listboxes when opened
{
- if( menu->items[ i ]->type == ITEM_TYPE_LISTBOX )
+ if( Item_IsListBox( menu->items[ i ] ) )
{
- menu->items[ i ]->cursorPos = 0;
- menu->items[ i ]->typeData.list->startPos = 0;
- DC->feederSelection( menu->items[ i ]->feederID, 0 );
+ menu->items[ i ]->cursorPos = DC->feederInitialise( menu->items[ i ]->feederID );
+ Item_ListBox_SetStartPos( menu->items[ i ], 0 );
+ DC->feederSelection( menu->items[ i ]->feederID, menu->items[ i ]->cursorPos );
}
- else if( menu->items[ i ]->type == ITEM_TYPE_COMBO )
+ else if( menu->items[ i ]->type == ITEM_TYPE_CYCLE )
{
- menu->items[ i ]->typeData.combo->cursorPos =
+ menu->items[ i ]->typeData.cycle->cursorPos =
DC->feederInitialise( menu->items[ i ]->feederID );
}
@@ -3977,10 +3858,10 @@ qboolean Menus_ReplaceActive( menuDef_t *menu )
if( openMenuCount < 1 )
return qfalse;
- active = menuStack[ openMenuCount - 1];
+ active = menuStack[ openMenuCount - 1 ];
- if( !( active->window.flags & WINDOW_HASFOCUS ) ||
- !( active->window.flags & WINDOW_VISIBLE ) )
+ if( !( active->window.flags & WINDOW_HASFOCUS ) ||
+ !( active->window.flags & WINDOW_VISIBLE ) )
{
return qfalse;
}
@@ -3990,8 +3871,8 @@ qboolean Menus_ReplaceActive( menuDef_t *menu )
if( menu->itemCount != active->itemCount )
return qfalse;
-
- for( i = 0; i < menu->itemCount; i++ )
+
+ for( i = 0; i < menu->itemCount; i++ )
{
if( menu->items[ i ]->type != active->items[ i ]->type )
return qfalse;
@@ -4007,14 +3888,7 @@ qboolean Menus_ReplaceActive( menuDef_t *menu )
item.parent = menu;
Item_RunScript( &item, menu->onOpen );
}
-
- for( i = 0; i < menu->itemCount; i++ )
- {
- menu->items[ i ]->cursorPos = active->items[ i ]->cursorPos;
- menu->items[ i ]->typeData.list->startPos = active->items[ i ]->typeData.list->startPos;
- menu->items[ i ]->feederID = active->items[ i ]->feederID;
- menu->items[ i ]->typeData.combo->cursorPos = active->items[ i ]->typeData.combo->cursorPos;
- }
+
return qtrue;
}
@@ -4134,12 +4008,17 @@ void Menu_HandleKey( menuDef_t *menu, int key, qboolean down )
}
}
- // get the item with focus
- for( i = 0; i < menu->itemCount; i++ )
+ if( g_comboBoxItem == NULL )
{
- if( menu->items[i]->window.flags & WINDOW_HASFOCUS )
- item = menu->items[i];
+ // get the item with focus
+ for( i = 0; i < menu->itemCount; i++ )
+ {
+ if( menu->items[i]->window.flags & WINDOW_HASFOCUS )
+ item = menu->items[i];
+ }
}
+ else
+ item = g_comboBoxItem;
if( item != NULL )
{
@@ -4973,7 +4852,7 @@ void Item_Multi_Paint( itemDef_t *item )
UI_Text_Paint( item->textRect.x, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle );
}
-void Item_Combobox_Paint( itemDef_t *item )
+void Item_Cycle_Paint( itemDef_t *item )
{
vec4_t newColor;
const char *text = "";
@@ -4984,8 +4863,8 @@ void Item_Combobox_Paint( itemDef_t *item )
else
memcpy( &newColor, &item->window.foreColor, sizeof( vec4_t ) );
- if( item->typeData.combo )
- text = DC->feederItemText( item->feederID, item->typeData.combo->cursorPos,
+ if( item->typeData.cycle )
+ text = DC->feederItemText( item->feederID, item->typeData.cycle->cursorPos,
0, NULL );
if( item->text )
@@ -5422,16 +5301,6 @@ qboolean Item_Bind_HandleKey( itemDef_t *item, int key, qboolean down )
}
-
-void AdjustFrom640( float *x, float *y, float *w, float *h )
-{
- //*x = *x * DC->scale + DC->bias;
- *x *= DC->xscale;
- *y *= DC->yscale;
- *w *= DC->xscale;
- *h *= DC->yscale;
-}
-
void Item_Model_Paint( itemDef_t *item )
{
float x, y, w, h;
@@ -5456,7 +5325,7 @@ void Item_Model_Paint( itemDef_t *item )
w = item->window.rect.w - 2;
h = item->window.rect.h - 2;
- AdjustFrom640( &x, &y, &w, &h );
+ UI_AdjustFrom640( &x, &y, &w, &h );
refdef.x = x;
refdef.y = y;
@@ -5524,294 +5393,222 @@ void Item_Model_Paint( itemDef_t *item )
}
-void Item_Image_Paint( itemDef_t *item )
+void Item_ListBoxRow_Paint( itemDef_t *item, int row, int renderPos, qboolean highlight, qboolean scrollbar )
{
- if( item == NULL )
- return;
-
- DC->drawHandlePic( item->window.rect.x + 1, item->window.rect.y + 1,
- item->window.rect.w - 2, item->window.rect.h - 2, item->asset );
-}
+ float x, y, w;
+ listBoxDef_t *listPtr = item->typeData.list;
+ menuDef_t *menu = ( menuDef_t * )item->parent;
+ float one, two;
-void Item_ListBox_Paint( itemDef_t *item )
-{
- float x, y, size, thumb;
- int i, count;
- qhandle_t image;
- qhandle_t optionalImage;
- listBoxDef_t *listPtr = item->typeData.list;
- menuDef_t *menu = ( menuDef_t * )item->parent;
- float one, two;
+ one = 1.0f * DC->aspectScale;
+ two = 2.0f * DC->aspectScale;
- if( menu->window.aspectBias != ASPECT_NONE || item->window.aspectBias != ASPECT_NONE )
- {
- one = 1.0f * DC->aspectScale;
- two = 2.0f * DC->aspectScale;
- }
- else
- {
- one = 1.0f;
- two = 2.0f;
- }
+ x = SCROLLBAR_X( item );
+ y = SCROLLBAR_Y( item ) + ( listPtr->elementHeight * renderPos );
+ w = item->window.rect.w - ( two * item->window.borderSize );
- // the listbox is horizontal or vertical and has a fixed size scroll bar going either direction
- // elements are enumerated from the DC and either text or image handles are acquired from the DC as well
- // textscale is used to size the text, textalignx and textaligny are used to size image elements
- // there is no clipping available so only the last completely visible item is painted
- count = DC->feederCount( item->feederID );
+ if( scrollbar )
+ w -= SCROLLBAR_ARROW_WIDTH;
- // default is vertical if horizontal flag is not here
- if( item->window.flags & WINDOW_HORIZONTAL )
+ if( listPtr->elementStyle == LISTBOX_IMAGE )
{
- //FIXME: unmaintained cruft?
+ qhandle_t image = DC->feederItemImage( item->feederID, row );
- if( !listPtr->noscrollbar )
- {
- // draw scrollbar in bottom of the window
- // bar
- x = item->window.rect.x + 1;
- y = item->window.rect.y + item->window.rect.h - SCROLLBAR_HEIGHT - 1;
- DC->drawHandlePic( x, y, SCROLLBAR_WIDTH, SCROLLBAR_HEIGHT, DC->Assets.scrollBarArrowLeft );
- x += SCROLLBAR_WIDTH - 1;
- size = item->window.rect.w - ( SCROLLBAR_WIDTH * 2 );
- DC->drawHandlePic( x, y, size + 1, SCROLLBAR_HEIGHT, DC->Assets.scrollBar );
- x += size - 1;
- DC->drawHandlePic( x, y, SCROLLBAR_WIDTH, SCROLLBAR_HEIGHT, DC->Assets.scrollBarArrowRight );
- // thumb
- thumb = Item_ListBox_ThumbDrawPosition( item );//Item_ListBox_ThumbPosition(item);
+ UI_SetClipRegion( x, y, listPtr->elementWidth, listPtr->elementHeight );
- if( thumb > x - SCROLLBAR_WIDTH - 1 )
- thumb = x - SCROLLBAR_WIDTH - 1;
+ if( image )
+ DC->drawHandlePic( x + one, y + 1.0f, listPtr->elementWidth - two, listPtr->elementHeight - 2.0f, image );
- DC->drawHandlePic( thumb, y, SCROLLBAR_WIDTH, SCROLLBAR_HEIGHT, DC->Assets.scrollBarThumb );
- //
- listPtr->endPos = listPtr->startPos;
+ if( highlight && row == item->cursorPos )
+ {
+ DC->drawRect( x, y, listPtr->elementWidth, listPtr->elementHeight,
+ item->window.borderSize, item->window.borderColor );
}
- size = item->window.rect.w - 2;
- // items
- // size contains max available space
+ UI_ClearClipRegion( );
+ }
+ else
+ {
+ const float m = UI_Text_EmHeight( item->textscale );
+ char text[ MAX_STRING_CHARS ];
+ qhandle_t optionalImage;
- if( listPtr->elementStyle == LISTBOX_IMAGE )
+ if( listPtr->numColumns > 0 )
{
- // fit = 0;
- x = item->window.rect.x + 1;
- y = item->window.rect.y + 1;
+ int j;
- for( i = listPtr->startPos; i < count; i++ )
+ for( j = 0; j < listPtr->numColumns; j++ )
{
- // always draw at least one
- // which may overdraw the box if it is too small for the element
- image = DC->feederItemImage( item->feederID, i );
+ float columnPos;
+ float width, height, yOffset;
- if( image )
- DC->drawHandlePic( x + 1, y + 1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image );
-
- if( i == item->cursorPos )
+ if( menu->window.aspectBias != ASPECT_NONE || item->window.aspectBias != ASPECT_NONE )
{
- DC->drawRect( x, y, listPtr->elementWidth - 1, listPtr->elementHeight - 1,
- item->window.borderSize, item->window.borderColor );
+ columnPos = ( listPtr->columnInfo[ j ].pos + 4.0f ) * DC->aspectScale;
+ width = listPtr->columnInfo[ j ].width * DC->aspectScale;
}
-
- listPtr->endPos++;
- size -= listPtr->elementWidth;
-
- if( size < listPtr->elementWidth )
+ else
{
- listPtr->drawPadding = size; //listPtr->elementWidth - size;
- break;
+ columnPos = ( listPtr->columnInfo[ j ].pos + 4.0f );
+ width = listPtr->columnInfo[ j ].width;
}
- x += listPtr->elementWidth;
- // fit++;
- }
- }
- }
- else
- {
- if( !listPtr->noscrollbar )
- {
- // draw scrollbar to right side of the window
- x = item->window.rect.x + item->window.rect.w - SCROLLBAR_WIDTH - one;
- y = item->window.rect.y + 1;
- DC->drawHandlePic( x, y, SCROLLBAR_WIDTH, SCROLLBAR_HEIGHT, DC->Assets.scrollBarArrowUp );
- y += SCROLLBAR_HEIGHT - 1;
-
- listPtr->endPos = listPtr->startPos;
- size = item->window.rect.h - ( SCROLLBAR_HEIGHT * 2 );
- DC->drawHandlePic( x, y, SCROLLBAR_WIDTH, size + 1, DC->Assets.scrollBar );
- y += size - 1;
- DC->drawHandlePic( x, y, SCROLLBAR_WIDTH, SCROLLBAR_HEIGHT, DC->Assets.scrollBarArrowDown );
- // thumb
- thumb = Item_ListBox_ThumbDrawPosition( item );//Item_ListBox_ThumbPosition(item);
+ height = listPtr->columnInfo[ j ].width;
+ yOffset = y + ( ( listPtr->elementHeight - height ) / 2.0f );
- if( thumb > y - SCROLLBAR_HEIGHT - 1 )
- thumb = y - SCROLLBAR_HEIGHT - 1;
+ Q_strncpyz( text, DC->feederItemText( item->feederID, row, j, &optionalImage ), sizeof( text ) );
- DC->drawHandlePic( x, thumb, SCROLLBAR_WIDTH, SCROLLBAR_HEIGHT, DC->Assets.scrollBarThumb );
- }
+ UI_SetClipRegion( x + columnPos, yOffset, width, height );
- // adjust size for item painting
- size = item->window.rect.h - 2;
+ if( optionalImage >= 0 )
+ DC->drawHandlePic( x + columnPos, yOffset, width, height, optionalImage );
+ else if( text[ 0 ] )
+ {
+ float alignOffset = 0.0f, tw;
- if( listPtr->elementStyle == LISTBOX_IMAGE )
- {
- // fit = 0;
- x = item->window.rect.x + one;
- y = item->window.rect.y + 1;
+ tw = UI_Text_Width( text, item->textscale, 0 );
- for( i = listPtr->startPos; i < count; i++ )
- {
- // always draw at least one
- // which may overdraw the box if it is too small for the element
- image = DC->feederItemImage( item->feederID, i );
+ switch( listPtr->columnInfo[ j ].align )
+ {
+ case ALIGN_LEFT:
+ alignOffset = 0.0f;
+ break;
- if( image )
- DC->drawHandlePic( x + one, y + 1, listPtr->elementWidth - two, listPtr->elementHeight - 2, image );
+ case ALIGN_RIGHT:
+ alignOffset = width - tw;
+ break;
- if( i == item->cursorPos )
- {
- DC->drawRect( x, y, listPtr->elementWidth - one, listPtr->elementHeight - 1,
- item->window.borderSize, item->window.borderColor );
- }
+ case ALIGN_CENTER:
+ alignOffset = ( width / 2.0f ) - ( tw / 2.0f );
+ break;
- listPtr->endPos++;
- size -= listPtr->elementWidth;
+ default:
+ alignOffset = 0.0f;
+ }
- if( size < listPtr->elementHeight )
- {
- listPtr->drawPadding = listPtr->elementHeight - size;
- break;
+ UI_Text_Paint( x + columnPos + alignOffset,
+ y + m + ( ( listPtr->elementHeight - m ) / 2.0f ),
+ item->textscale, item->window.foreColor, text, 0,
+ 0, item->textStyle );
}
- y += listPtr->elementHeight;
- // fit++;
+ UI_ClearClipRegion( );
}
}
else
{
- float m = UI_Text_EmHeight( item->textscale );
- x = item->window.rect.x + one;
- y = item->window.rect.y + 1;
+ float offset;
- for( i = listPtr->startPos; i < count; i++ )
- {
- char text[ MAX_STRING_CHARS ];
- // always draw at least one
- // which may overdraw the box if it is too small for the element
+ if( menu->window.aspectBias != ASPECT_NONE || item->window.aspectBias != ASPECT_NONE )
+ offset = 4.0f * DC->aspectScale;
+ else
+ offset = 4.0f;
- if( listPtr->numColumns > 0 )
- {
- int j;
+ Q_strncpyz( text, DC->feederItemText( item->feederID, row, 0, &optionalImage ), sizeof( text ) );
- for( j = 0; j < listPtr->numColumns; j++ )
- {
- float columnPos;
- float width, height;
+ UI_SetClipRegion( x, y, w, listPtr->elementHeight );
- if( menu->window.aspectBias != ASPECT_NONE || item->window.aspectBias != ASPECT_NONE )
- {
- columnPos = ( listPtr->columnInfo[ j ].pos + 4.0f ) * DC->aspectScale;
- width = listPtr->columnInfo[ j ].width * DC->aspectScale;
- }
- else
- {
- columnPos = ( listPtr->columnInfo[ j ].pos + 4.0f );
- width = listPtr->columnInfo[ j ].width;
- }
+ if( optionalImage >= 0 )
+ DC->drawHandlePic( x + offset, y, listPtr->elementHeight, listPtr->elementHeight, optionalImage );
+ else if( text[ 0 ] )
+ {
+ UI_Text_Paint( x + offset, y + m + ( ( listPtr->elementHeight - m ) / 2.0f ),
+ item->textscale, item->window.foreColor, text, 0,
+ 0, item->textStyle );
+ }
- height = listPtr->columnInfo[ j ].width;
+ UI_ClearClipRegion( );
+ }
- Q_strncpyz( text, DC->feederItemText( item->feederID, i, j, &optionalImage ), sizeof( text ) );
+ if( highlight && row == item->cursorPos )
+ DC->fillRect( x, y, w, listPtr->elementHeight, item->window.outlineColor );
+ }
+}
- if( optionalImage >= 0 )
- {
- DC->drawHandlePic( x + columnPos, y + ( ( listPtr->elementHeight - height ) / 2.0f ),
- width, height, optionalImage );
- }
- else if( text[ 0 ] )
- {
- int alignOffset = 0.0f, tw;
+void Item_ListBox_Paint( itemDef_t *item )
+{
+ float size;
+ int i;
+ listBoxDef_t *listPtr = item->typeData.list;
+ int count = DC->feederCount( item->feederID );
+ qboolean scrollbar = !listPtr->noscrollbar &&
+ count > Item_ListBox_NumItemsForItemHeight( item );
- tw = UI_Text_Width( text, item->textscale, 0 );
+ if( scrollbar )
+ {
+ float x = SCROLLBAR_SLIDER_X( item );
+ float y = SCROLLBAR_Y( item );
+ float thumbY = Item_ListBox_ThumbDrawPosition( item );
- // Shorten the string if it's too long
+ // Up arrow
+ DC->drawHandlePic( x, y, SCROLLBAR_ARROW_WIDTH, SCROLLBAR_ARROW_HEIGHT, DC->Assets.scrollBarArrowUp );
+ y = SCROLLBAR_SLIDER_Y( item );
- while( tw > width && strlen( text ) > 0 )
- {
- text[ strlen( text ) - 1 ] = '\0';
- tw = UI_Text_Width( text, item->textscale, 0 );
- }
+ // Scroll bar
+ size = SCROLLBAR_SLIDER_HEIGHT( item );
+ DC->drawHandlePic( x, y, SCROLLBAR_ARROW_WIDTH, size, DC->Assets.scrollBar );
+ y = SCROLLBAR_SLIDER_Y( item ) + size;
- switch( listPtr->columnInfo[ j ].align )
- {
- case ALIGN_LEFT:
- alignOffset = 0.0f;
- break;
+ // Down arrow
+ DC->drawHandlePic( x, y, SCROLLBAR_ARROW_WIDTH, SCROLLBAR_ARROW_HEIGHT, DC->Assets.scrollBarArrowDown );
- case ALIGN_RIGHT:
- alignOffset = width - tw;
- break;
+ // Thumb
+ DC->drawHandlePic( x, thumbY, SCROLLBAR_ARROW_WIDTH, SCROLLBAR_ARROW_HEIGHT, DC->Assets.scrollBarThumb );
+ }
- case ALIGN_CENTER:
- alignOffset = ( width / 2.0f ) - ( tw / 2.0f );
- break;
+ // Paint rows
+ for( i = listPtr->startPos; i < listPtr->endPos; i++ )
+ Item_ListBoxRow_Paint( item, i, i - listPtr->startPos, qtrue, scrollbar );
+}
- default:
- alignOffset = 0.0f;
- }
+void Item_Paint( itemDef_t *item );
- UI_Text_Paint( x + columnPos + alignOffset,
- y + m + ( ( listPtr->elementHeight - m ) / 2.0f ),
- item->textscale, item->window.foreColor, text, 0,
- 0, item->textStyle );
- }
- }
- }
- else
- {
- float offset;
+void Item_ComboBox_Paint( itemDef_t *item )
+{
+ float x, y, h;
- if( menu->window.aspectBias != ASPECT_NONE || item->window.aspectBias != ASPECT_NONE )
- offset = 4.0f * DC->aspectScale;
- else
- offset = 4.0f;
+ x = SCROLLBAR_SLIDER_X( item );
+ y = SCROLLBAR_Y( item );
+ h = item->window.rect.h - 2.0f;
- Q_strncpyz( text, DC->feederItemText( item->feederID, i, 0, &optionalImage ), sizeof( text ) );
+ // Down arrow
+ DC->drawHandlePic( x, y, SCROLLBAR_ARROW_WIDTH, h, DC->Assets.scrollBarArrowDown );
- if( optionalImage >= 0 )
- DC->drawHandlePic( x + offset, y, listPtr->elementHeight, listPtr->elementHeight, optionalImage );
- else if( text[ 0 ] )
- {
- UI_Text_Paint( x + offset, y + m + ( ( listPtr->elementHeight - m ) / 2.0f ),
- item->textscale, item->window.foreColor, text, 0,
- 0, item->textStyle );
- }
- }
+ Item_ListBoxRow_Paint( item, item->cursorPos, 0, qfalse, qtrue );
- if( i == item->cursorPos )
- {
- DC->fillRect( x, y, item->window.rect.w - SCROLLBAR_WIDTH - ( two * item->window.borderSize ),
- listPtr->elementHeight, item->window.outlineColor );
- }
+ if( g_comboBoxItem != NULL )
+ {
+ qboolean cast = Item_ComboBox_MaybeCastToListBox( item );
+ Item_Paint( item );
+ Item_ComboBox_MaybeUnCastFromListBox( item, cast );
+ }
+}
- listPtr->endPos++;
- size -= listPtr->elementHeight;
+void Item_ListBox_Update( itemDef_t *item )
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+ int feederCount = DC->feederCount( item->feederID );
- if( size < listPtr->elementHeight )
- {
- listPtr->drawPadding = listPtr->elementHeight - size;
- break;
- }
+ if( listPtr->lastFeederCount != feederCount )
+ {
+ if( listPtr->resetonfeederchange )
+ {
+ item->cursorPos = DC->feederInitialise( item->feederID );
+ Item_ListBox_SetStartPos( item, 0 );
+ DC->feederSelection( item->feederID, item->cursorPos );
+ }
+ else
+ {
+ // Make sure endPos is up-to-date
+ Item_ListBox_SetStartPos( item, listPtr->startPos );
- y += listPtr->elementHeight;
- // fit++;
- }
+ // If the selection is off the end now, select the last element
+ if( item->cursorPos >= feederCount )
+ item->cursorPos = feederCount - 1;
}
}
- // FIXME: hacky fix to off-by-one bug
- listPtr->endPos--;
+ listPtr->lastFeederCount = feederCount;
}
void Item_OwnerDraw_Paint( itemDef_t *item )
@@ -5893,6 +5690,15 @@ void Item_OwnerDraw_Paint( itemDef_t *item )
}
+void Item_Update( itemDef_t *item )
+{
+ if( item == NULL )
+ return;
+
+ if( Item_IsListBox( item ) )
+ Item_ListBox_Update( item );
+}
+
void Item_Paint( itemDef_t *item )
{
vec4_t red;
@@ -6067,7 +5873,7 @@ void Item_Paint( itemDef_t *item )
if( !( item->window.flags & WINDOW_VISIBLE ) )
return;
- Window_Paint( &item->window, parent->fadeAmount , parent->fadeClamp, parent->fadeCycle );
+ Window_Paint( &item->window, parent->fadeAmount, parent->fadeClamp, parent->fadeCycle );
if( DC->getCVarValue( "ui_developer" ) )
{
@@ -6095,17 +5901,17 @@ void Item_Paint( itemDef_t *item )
case ITEM_TYPE_CHECKBOX:
break;
- case ITEM_TYPE_COMBO:
- Item_Combobox_Paint( item );
+ case ITEM_TYPE_CYCLE:
+ Item_Cycle_Paint( item );
break;
case ITEM_TYPE_LISTBOX:
Item_ListBox_Paint( item );
break;
- //case ITEM_TYPE_IMAGE:
- // Item_Image_Paint(item);
- // break;
+ case ITEM_TYPE_COMBOBOX:
+ Item_ComboBox_Paint( item );
+ break;
case ITEM_TYPE_MODEL:
Item_Model_Paint( item );
@@ -6185,9 +5991,14 @@ void Menu_ScrollFeeder( menuDef_t *menu, int feeder, qboolean down )
for( i = 0; i < menu->itemCount; i++ )
{
- if( menu->items[i]->feederID == feeder )
+ itemDef_t *item = menu->items[ i ];
+
+ if( item->feederID == feeder )
{
- Item_ListBox_HandleKey( menu->items[i], ( down ) ? K_DOWNARROW : K_UPARROW, qtrue, qtrue );
+ qboolean cast = Item_ComboBox_MaybeCastToListBox( item );
+ Item_ListBox_HandleKey( item, down ? K_DOWNARROW : K_UPARROW, qtrue, qtrue );
+ Item_ComboBox_MaybeUnCastFromListBox( item, cast );
+
return;
}
}
@@ -6214,10 +6025,10 @@ void Menu_SetFeederSelection( menuDef_t *menu, int feeder, int index, const char
{
if( menu->items[i]->feederID == feeder )
{
- if( menu->items[i]->type == ITEM_TYPE_LISTBOX && index == 0 )
+ if( Item_IsListBox( menu->items[i] ) && index == 0 )
{
menu->items[ i ]->typeData.list->cursorPos = 0;
- menu->items[ i ]->typeData.list->startPos = 0;
+ Item_ListBox_SetStartPos( menu->items[ i ], 0 );
}
menu->items[i]->cursorPos = index;
@@ -6297,12 +6108,41 @@ void Item_Init( itemDef_t *item )
item->window.aspectBias = ASPECT_NONE;
}
+static qboolean Item_HandleMouseMove( itemDef_t *item, float x, float y, int pass, qboolean focusSet )
+{
+ if( Rect_ContainsPoint( &item->window.rect, x, y ) )
+ {
+ if( pass == 1 )
+ {
+ if( item->type == ITEM_TYPE_TEXT && item->text )
+ {
+ if( !Rect_ContainsPoint( Item_CorrectedTextRect( item ), x, y ) )
+ return qtrue;
+ }
+
+ // if we are over an item
+ if( IsVisible( item->window.flags ) )
+ {
+ // different one
+ Item_MouseEnter( item, x, y );
+
+ if( !focusSet )
+ focusSet = Item_SetFocus( item, x, y );
+ }
+ }
+
+ return qtrue;
+ }
+
+ return qfalse;
+}
+
void Menu_HandleMouseMove( menuDef_t *menu, float x, float y )
{
int i, pass;
qboolean focusSet = qfalse;
-
- itemDef_t *overItem;
+ qboolean result;
+ qboolean cast;
if( menu == NULL )
return;
@@ -6319,65 +6159,60 @@ void Menu_HandleMouseMove( menuDef_t *menu, float x, float y )
if( g_waitingForKey || g_editingField )
return;
+ if( g_comboBoxItem != NULL )
+ {
+ Item_SetFocus( g_comboBoxItem, x, y );
+ focusSet = qtrue;
+ }
+
// FIXME: this is the whole issue of focus vs. mouse over..
// need a better overall solution as i don't like going through everything twice
for( pass = 0; pass < 2; pass++ )
{
for( i = 0; i < menu->itemCount; i++ )
{
+ itemDef_t *item = menu->items[ i ];
+
// turn off focus each item
// menu->items[i].window.flags &= ~WINDOW_HASFOCUS;
- if( !( menu->items[i]->window.flags & ( WINDOW_VISIBLE | WINDOW_FORCED ) ) )
+ if( !( item->window.flags & ( WINDOW_VISIBLE | WINDOW_FORCED ) ) )
continue;
// items can be enabled and disabled based on cvars
- if( menu->items[i]->cvarFlags & ( CVAR_ENABLE | CVAR_DISABLE ) &&
- !Item_EnableShowViaCvar( menu->items[i], CVAR_ENABLE ) )
+ if( item->cvarFlags & ( CVAR_ENABLE | CVAR_DISABLE ) &&
+ !Item_EnableShowViaCvar( item, CVAR_ENABLE ) )
continue;
- if( menu->items[i]->cvarFlags & ( CVAR_SHOW | CVAR_HIDE ) &&
- !Item_EnableShowViaCvar( menu->items[i], CVAR_SHOW ) )
+ if( item->cvarFlags & ( CVAR_SHOW | CVAR_HIDE ) &&
+ !Item_EnableShowViaCvar( item, CVAR_SHOW ) )
continue;
+ cast = Item_ComboBox_MaybeCastToListBox( item );
+ result = Item_HandleMouseMove( item, x, y, pass, focusSet );
+ Item_ComboBox_MaybeUnCastFromListBox( item, cast );
-
- if( Rect_ContainsPoint( &menu->items[i]->window.rect, x, y ) )
- {
- if( pass == 1 )
- {
- overItem = menu->items[i];
-
- if( overItem->type == ITEM_TYPE_TEXT && overItem->text )
- {
- if( !Rect_ContainsPoint( Item_CorrectedTextRect( overItem ), x, y ) )
- continue;
- }
-
- // if we are over an item
- if( IsVisible( overItem->window.flags ) )
- {
- // different one
- Item_MouseEnter( overItem, x, y );
- // Item_SetMouseOver(overItem, qtrue);
-
- // if item is not a decoration see if it can take focus
-
- if( !focusSet )
- focusSet = Item_SetFocus( overItem, x, y );
- }
- }
- }
- else if( menu->items[i]->window.flags & WINDOW_MOUSEOVER )
+ if( !result && item->window.flags & WINDOW_MOUSEOVER )
{
- Item_MouseLeave( menu->items[i] );
- Item_SetMouseOver( menu->items[i], qfalse );
+ Item_MouseLeave( item );
+ Item_SetMouseOver( item, qfalse );
}
}
}
}
+void Menu_Update( menuDef_t *menu )
+{
+ int i;
+
+ if( menu == NULL )
+ return;
+
+ for( i = 0; i < menu->itemCount; i++ )
+ Item_Update( menu->items[ i ] );
+}
+
void Menu_Paint( menuDef_t *menu, qboolean forcePaint )
{
int i;
@@ -6385,7 +6220,7 @@ void Menu_Paint( menuDef_t *menu, qboolean forcePaint )
if( menu == NULL )
return;
- if( !( menu->window.flags & WINDOW_VISIBLE ) && !forcePaint )
+ if( !( menu->window.flags & WINDOW_VISIBLE ) && !forcePaint )
return;
if( menu->window.ownerDrawFlags && DC->ownerDrawVisible && !DC->ownerDrawVisible( menu->window.ownerDrawFlags ) )
@@ -6501,9 +6336,10 @@ itemDataType_t Item_DataType( itemDef_t *item )
return TYPE_NONE;
case ITEM_TYPE_LISTBOX:
+ case ITEM_TYPE_COMBOBOX:
return TYPE_LIST;
- case ITEM_TYPE_COMBO:
+ case ITEM_TYPE_CYCLE:
return TYPE_COMBO;
case ITEM_TYPE_EDITFIELD:
@@ -6544,6 +6380,24 @@ static ID_INLINE qboolean Item_IsEditField( itemDef_t *item )
/*
===============
+Item_IsListBox
+===============
+*/
+static ID_INLINE qboolean Item_IsListBox( itemDef_t *item )
+{
+ switch( item->type )
+ {
+ case ITEM_TYPE_LISTBOX:
+ case ITEM_TYPE_COMBOBOX:
+ return qtrue;
+
+ default:
+ return qfalse;
+ }
+}
+
+/*
+===============
Item Keyword Parse functions
===============
*/
@@ -6693,21 +6547,21 @@ qboolean ItemParse_noscrollbar( itemDef_t *item, int handle )
return qtrue;
}
-// auto wrapped
-qboolean ItemParse_wrapped( itemDef_t *item, int handle )
+// resetonfeederchange
+qboolean ItemParse_resetonfeederchange( itemDef_t *item, int handle )
{
- item->window.flags |= WINDOW_WRAPPED;
+ item->typeData.list->resetonfeederchange = qtrue;
return qtrue;
}
-
-// horizontalscroll
-qboolean ItemParse_horizontalscroll( itemDef_t *item, int handle )
+// auto wrapped
+qboolean ItemParse_wrapped( itemDef_t *item, int handle )
{
- item->window.flags |= WINDOW_HORIZONTAL;
+ item->window.flags |= WINDOW_WRAPPED;
return qtrue;
}
+
// type <integer>
qboolean ItemParse_type( itemDef_t *item, int handle )
{
@@ -6730,13 +6584,14 @@ qboolean ItemParse_type( itemDef_t *item, int handle )
switch( item->type )
{
case ITEM_TYPE_LISTBOX:
+ case ITEM_TYPE_COMBOBOX:
item->typeData.list = UI_Alloc( sizeof( listBoxDef_t ) );
memset( item->typeData.list, 0, sizeof( listBoxDef_t ) );
break;
- case ITEM_TYPE_COMBO:
- item->typeData.combo = UI_Alloc( sizeof( comboBoxDef_t ) );
- memset( item->typeData.combo, 0, sizeof( comboBoxDef_t ) );
+ case ITEM_TYPE_CYCLE:
+ item->typeData.cycle = UI_Alloc( sizeof( cycleDef_t ) );
+ memset( item->typeData.cycle, 0, sizeof( cycleDef_t ) );
break;
case ITEM_TYPE_EDITFIELD:
@@ -6771,19 +6626,23 @@ qboolean ItemParse_type( itemDef_t *item, int handle )
}
// elementwidth, used for listbox image elements
-// uses textalignx for storage
qboolean ItemParse_elementwidth( itemDef_t *item, int handle )
{
return PC_Float_Parse( handle, &item->typeData.list->elementWidth );
}
// elementheight, used for listbox image elements
-// uses textaligny for storage
qboolean ItemParse_elementheight( itemDef_t *item, int handle )
{
return PC_Float_Parse( handle, &item->typeData.list->elementHeight );
}
+// dropitems, number of items to drop from a combobox
+qboolean ItemParse_dropitems( itemDef_t *item, int handle )
+{
+ return PC_Int_Parse( handle, &item->typeData.list->dropItems );
+}
+
// feeder <int>
qboolean ItemParse_feeder( itemDef_t *item, int handle )
{
@@ -7353,10 +7212,11 @@ keywordHash_t itemParseKeywords[] = {
{"decoration", ItemParse_decoration, TYPE_ANY},
{"notselectable", ItemParse_notselectable, TYPE_LIST},
{"noscrollbar", ItemParse_noscrollbar, TYPE_LIST},
+ {"resetonfeederchange", ItemParse_resetonfeederchange, TYPE_LIST},
{"wrapped", ItemParse_wrapped, TYPE_ANY},
- {"horizontalscroll", ItemParse_horizontalscroll, TYPE_ANY},
{"elementwidth", ItemParse_elementwidth, TYPE_LIST},
{"elementheight", ItemParse_elementheight, TYPE_LIST},
+ {"dropitems", ItemParse_dropitems, TYPE_LIST},
{"feeder", ItemParse_feeder, TYPE_ANY},
{"elementtype", ItemParse_elementtype, TYPE_LIST},
{"columns", ItemParse_columns, TYPE_LIST},
@@ -7493,15 +7353,14 @@ void Item_InitControls( itemDef_t *item )
if( item == NULL )
return;
- if( item->type == ITEM_TYPE_LISTBOX )
+ if( Item_IsListBox( item ) )
{
item->cursorPos = 0;
if( item->typeData.list )
{
item->typeData.list->cursorPos = 0;
- item->typeData.list->startPos = 0;
- item->typeData.list->endPos = 0;
+ Item_ListBox_SetStartPos( item, 0 );
item->typeData.list->cursorPos = 0;
}
}
@@ -7994,6 +7853,14 @@ int Menu_Count( void )
return menuCount;
}
+void Menu_UpdateAll( void )
+{
+ int i;
+
+ for( i = 0; i < openMenuCount; i++ )
+ Menu_Update( menuStack[ i ] );
+}
+
void Menu_PaintAll( void )
{
int i;
@@ -8012,7 +7879,7 @@ void Menu_PaintAll( void )
}
for( i = 0; i < openMenuCount; i++ )
- Menu_Paint( menuStack[i], qfalse );
+ Menu_Paint( menuStack[ i ], qfalse );
if( DC->getCVarValue( "ui_developer" ) )
{
diff --git a/src/ui/ui_shared.h b/src/ui/ui_shared.h
index 462a4bb4..29224757 100644
--- a/src/ui/ui_shared.h
+++ b/src/ui/ui_shared.h
@@ -42,34 +42,34 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define MAX_OPEN_MENUS 16
#define WINDOW_MOUSEOVER 0x00000001 // mouse is over it, non exclusive
-#define WINDOW_HASFOCUS 0x00000002 // has cursor focus, exclusive
+#define WINDOW_HASFOCUS 0x00000002 // has cursor focus, exclusive
#define WINDOW_VISIBLE 0x00000004 // is visible
-#define WINDOW_GREY 0x00000008 // is visible but grey ( non-active )
-#define WINDOW_DECORATION 0x00000010 // for decoration only, no mouse, keyboard, etc..
+#define WINDOW_GREY 0x00000008 // is visible but grey ( non-active )
+#define WINDOW_DECORATION 0x00000010 // for decoration only, no mouse, keyboard, etc..
#define WINDOW_FADINGOUT 0x00000020 // fading out, non-active
-#define WINDOW_FADINGIN 0x00000040 // fading in
+#define WINDOW_FADINGIN 0x00000040 // fading in
#define WINDOW_MOUSEOVERTEXT 0x00000080 // mouse is over it, non exclusive
-#define WINDOW_INTRANSITION 0x00000100 // window is in transition
-#define WINDOW_FORECOLORSET 0x00000200 // forecolor was explicitly set ( used to color alpha images or not )
-#define WINDOW_HORIZONTAL 0x00000400 // for list boxes and sliders, vertical is default this is set of horizontal
-#define WINDOW_LB_LEFTARROW 0x00000800 // mouse is over left/up arrow
-#define WINDOW_LB_RIGHTARROW 0x00001000 // mouse is over right/down arrow
-#define WINDOW_LB_THUMB 0x00002000 // mouse is over thumb
+#define WINDOW_INTRANSITION 0x00000100 // window is in transition
+#define WINDOW_FORECOLORSET 0x00000200 // forecolor was explicitly set ( used to color alpha images or not )
+#define WINDOW_HORIZONTAL 0x00000400 // for list boxes and sliders, vertical is default this is set of horizontal
+#define WINDOW_LB_UPARROW 0x00000800 // mouse is over up arrow
+#define WINDOW_LB_DOWNARROW 0x00001000 // mouse is over down arrow
+#define WINDOW_LB_THUMB 0x00002000 // mouse is over thumb
#define WINDOW_LB_PGUP 0x00004000 // mouse is over page up
#define WINDOW_LB_PGDN 0x00008000 // mouse is over page down
-#define WINDOW_ORBITING 0x00010000 // item is in orbit
+#define WINDOW_ORBITING 0x00010000 // item is in orbit
#define WINDOW_OOB_CLICK 0x00020000 // close on out of bounds click
#define WINDOW_WRAPPED 0x00080000 // wrap text
-#define WINDOW_FORCED 0x00100000 // forced open
+#define WINDOW_FORCED 0x00100000 // forced open
#define WINDOW_POPUP 0x00200000 // popup
-#define WINDOW_BACKCOLORSET 0x00400000 // backcolor was explicitly set
-#define WINDOW_TIMEDVISIBLE 0x00800000 // visibility timing ( NOT implemented )
+#define WINDOW_BACKCOLORSET 0x00400000 // backcolor was explicitly set
+#define WINDOW_TIMEDVISIBLE 0x00800000 // visibility timing ( NOT implemented )
// CGAME cursor type bits
-#define CURSOR_NONE 0x00000001
-#define CURSOR_ARROW 0x00000002
-#define CURSOR_SIZER 0x00000004
+#define CURSOR_NONE 0x00000001
+#define CURSOR_ARROW 0x00000002
+#define CURSOR_SIZER 0x00000004
#ifdef CGAME
#define STRING_POOL_SIZE 128*1024
@@ -82,16 +82,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define MAX_EDITFIELD 256
#define ITEM_VALUE_OFFSET 8
-#define ART_FX_BASE "menu/art/fx_base"
-#define ART_FX_BLUE "menu/art/fx_blue"
-#define ART_FX_CYAN "menu/art/fx_cyan"
-#define ART_FX_GREEN "menu/art/fx_grn"
-#define ART_FX_RED "menu/art/fx_red"
-#define ART_FX_TEAL "menu/art/fx_teal"
-#define ART_FX_WHITE "menu/art/fx_white"
-#define ART_FX_YELLOW "menu/art/fx_yel"
+#define ART_FX_BASE "menu/art/fx_base"
+#define ART_FX_BLUE "menu/art/fx_blue"
+#define ART_FX_CYAN "menu/art/fx_cyan"
+#define ART_FX_GREEN "menu/art/fx_grn"
+#define ART_FX_RED "menu/art/fx_red"
+#define ART_FX_TEAL "menu/art/fx_teal"
+#define ART_FX_WHITE "menu/art/fx_white"
+#define ART_FX_YELLOW "menu/art/fx_yel"
-#define ASSET_GRADIENTBAR "ui/assets/gradientbar2.tga"
+#define ASSET_GRADIENTBAR "ui/assets/gradientbar2.tga"
#define ASSET_SCROLLBAR "ui/assets/scrollbar.tga"
#define ASSET_SCROLLBAR_ARROWDOWN "ui/assets/scrollbar_arrow_dwn_a.tga"
#define ASSET_SCROLLBAR_ARROWUP "ui/assets/scrollbar_arrow_up_a.tga"
@@ -100,9 +100,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define ASSET_SCROLL_THUMB "ui/assets/scrollbar_thumb.tga"
#define ASSET_SLIDER_BAR "ui/assets/slider2.tga"
#define ASSET_SLIDER_THUMB "ui/assets/sliderbutt_1.tga"
-#define SCROLLBAR_SIZE 16.0f
-#define SCROLLBAR_WIDTH (SCROLLBAR_SIZE*DC->aspectScale)
-#define SCROLLBAR_HEIGHT SCROLLBAR_SIZE
+
+#define SCROLLBAR_ARROW_SIZE 16.0f
+#define SCROLLBAR_ARROW_WIDTH (SCROLLBAR_ARROW_SIZE*DC->aspectScale)
+#define SCROLLBAR_ARROW_HEIGHT SCROLLBAR_ARROW_SIZE
+#define SCROLLBAR_SLIDER_X(_item) (_item->window.rect.x+_item->window.rect.w- \
+ SCROLLBAR_ARROW_WIDTH-DC->aspectScale)
+#define SCROLLBAR_SLIDER_Y(_item) (SCROLLBAR_Y(_item)+SCROLLBAR_ARROW_HEIGHT)
+#define SCROLLBAR_SLIDER_HEIGHT(_item) (_item->window.rect.h-(SCROLLBAR_ARROW_HEIGHT*2.0f)-2.0f)
+#define SCROLLBAR_X(_item) (_item->window.rect.x+DC->aspectScale)
+#define SCROLLBAR_Y(_item) (_item->window.rect.y+1.0f)
+#define SCROLLBAR_W(_item) (SCROLLBAR_SLIDER_X(_item)-SCROLLBAR_X(_item))
+#define SCROLLBAR_H(_item) (_item->window.rect.h-2.0f)
+
#define SLIDER_WIDTH (96.0f*DC->aspectScale)
#define SLIDER_HEIGHT 16.0f
#define SLIDER_THUMB_WIDTH (12.0f*DC->aspectScale)
@@ -191,24 +201,31 @@ typedef struct listBoxDef_s
{
int startPos;
int endPos;
- int drawPadding;
int cursorPos;
+
float elementWidth;
float elementHeight;
int elementStyle;
+ int dropItems;
+
int numColumns;
columnInfo_t columnInfo[MAX_LB_COLUMNS];
+
const char *doubleClick;
+
qboolean notselectable;
qboolean noscrollbar;
+
+ qboolean resetonfeederchange;
+ int lastFeederCount;
}
listBoxDef_t;
-typedef struct comboBoxDef_s
+typedef struct cycleDef_s
{
int cursorPos;
}
-comboBoxDef_t;
+cycleDef_t;
typedef struct editFieldDef_s
{
@@ -300,7 +317,7 @@ typedef struct itemDef_s
listBoxDef_t *list;
editFieldDef_t *edit;
multiDef_t *multi;
- comboBoxDef_t *combo;
+ cycleDef_t *cycle;
modelDef_t *model;
} typeData; // type specific data pointers
}
@@ -407,11 +424,11 @@ typedef struct
qboolean ( *getOverstrikeMode )( void );
void ( *startLocalSound )( sfxHandle_t sfx, int channelNum );
qboolean ( *ownerDrawHandleKey )( int ownerDraw, int key );
- int ( *feederCount )( float feederID );
- const char *( *feederItemText )( float feederID, int index, int column, qhandle_t *handle );
- qhandle_t ( *feederItemImage )( float feederID, int index );
- void ( *feederSelection )( float feederID, int index );
- int ( *feederInitialise )( float feederID );
+ int ( *feederCount )( int feederID );
+ const char *( *feederItemText )( int feederID, int index, int column, qhandle_t *handle );
+ qhandle_t ( *feederItemImage )( int feederID, int index );
+ void ( *feederSelection )( int feederID, int index );
+ int ( *feederInitialise )( int feederID );
void ( *keynumToStringBuf )( int keynum, char *buf, int buflen );
void ( *getBindingBuf )( int keynum, char *buf, int buflen );
void ( *setBinding )( int keynum, const char *binding );
@@ -475,6 +492,7 @@ qboolean PC_String_Parse( int handle, const char **out );
qboolean PC_Script_Parse( int handle, const char **out );
int Menu_Count( void );
void Menu_New( int handle );
+void Menu_UpdateAll( void );
void Menu_PaintAll( void );
menuDef_t *Menus_ActivateByName( const char *p );
menuDef_t *Menus_ReplaceActiveByName( const char *p );
@@ -510,6 +528,8 @@ void Controls_GetConfig( void );
void Controls_SetConfig( qboolean restart );
void Controls_SetDefaults( void );
+void trap_R_SetClipRegion( const float *region );
+
//for cg_draw.c
void Item_Text_Wrapped_Paint( itemDef_t *item );
const char *Item_Text_Wrap( const char *text, float scale, float width );