diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ui_demos.c | 25 | ||||
-rw-r--r-- | src/ui_local.h | 9 | ||||
-rw-r--r-- | src/ui_menu.c | 260 | ||||
-rw-r--r-- | src/ui_multiplayer.c | 4 |
4 files changed, 227 insertions, 71 deletions
diff --git a/src/ui_demos.c b/src/ui_demos.c index cec1608..b4edf45 100644 --- a/src/ui_demos.c +++ b/src/ui_demos.c @@ -339,7 +339,7 @@ static void BuildList(void) if (m_demos.list.numItems) { Change(&m_demos.list.generic); if (m_demos.list.sortdir) { - m_demos.list.sort(&m_demos.list, m_demos.list.sortcol); + m_demos.list.sort(&m_demos.list); } } @@ -475,9 +475,9 @@ static int namecmp(const void *p1, const void *p2) return Q_stricmp(s1, s2) * m_demos.list.sortdir; } -static menuSound_t Sort(menuList_t *self, int column) +static menuSound_t Sort(menuList_t *self) { - switch (column) { + switch (m_demos.list.sortcol) { case COL_NAME: case COL_MAP: case COL_POV: @@ -504,21 +504,21 @@ static void Size(menuFrameWork_t *self) m_demos.list.generic.height = uis.height - CHAR_HEIGHT * 2 - 1; w1 = 17 + m_demos.widest_map + m_demos.widest_pov; - w2 = uis.width - (w1 + 2) * CHAR_WIDTH - MLIST_SCROLLBAR_WIDTH; + w2 = uis.width - w1 * CHAR_WIDTH - MLIST_PADDING * 4 - MLIST_SCROLLBAR_WIDTH; if (w2 > 8 * CHAR_WIDTH) { // everything fits m_demos.list.columns[0].width = w2; - m_demos.list.columns[1].width = 12 * CHAR_WIDTH + CHAR_WIDTH / 2; - m_demos.list.columns[2].width = 5 * CHAR_WIDTH + CHAR_WIDTH / 2; - m_demos.list.columns[3].width = m_demos.widest_map * CHAR_WIDTH + CHAR_WIDTH / 2; - m_demos.list.columns[4].width = m_demos.widest_pov * CHAR_WIDTH + CHAR_WIDTH / 2; + m_demos.list.columns[1].width = 12 * CHAR_WIDTH + MLIST_PADDING; + m_demos.list.columns[2].width = 5 * CHAR_WIDTH + MLIST_PADDING; + m_demos.list.columns[3].width = m_demos.widest_map * CHAR_WIDTH + MLIST_PADDING; + m_demos.list.columns[4].width = m_demos.widest_pov * CHAR_WIDTH + MLIST_PADDING; m_demos.list.numcolumns = COL_MAX; } else { // map and pov don't fit - w2 = uis.width - (17 + 1) * CHAR_WIDTH - MLIST_SCROLLBAR_WIDTH; + w2 = uis.width - 17 * CHAR_WIDTH - MLIST_PADDING * 2 - MLIST_SCROLLBAR_WIDTH; m_demos.list.columns[0].width = w2; - m_demos.list.columns[1].width = 12 * CHAR_WIDTH + CHAR_WIDTH / 2; - m_demos.list.columns[2].width = 5 * CHAR_WIDTH + CHAR_WIDTH / 2; + m_demos.list.columns[1].width = 12 * CHAR_WIDTH + MLIST_PADDING; + m_demos.list.columns[2].width = 5 * CHAR_WIDTH + MLIST_PADDING; m_demos.list.columns[3].width = 0; m_demos.list.columns[4].width = 0; m_demos.list.numcolumns = COL_MAX - 2; @@ -588,7 +588,7 @@ static void ui_sortdemos_changed(cvar_t *self) } if (m_demos.list.items && m_demos.list.sortdir) { - m_demos.list.sort(&m_demos.list, m_demos.list.sortcol); + m_demos.list.sort(&m_demos.list); } } @@ -622,6 +622,7 @@ void M_Menu_Demos(void) m_demos.list.sortcol = COL_NAME; m_demos.list.extrasize = DEMO_EXTRASIZE; m_demos.list.sort = Sort; + m_demos.list.mlFlags = MLF_HEADER | MLF_SCROLLBAR; m_demos.list.columns[0].name = m_demos.browse; m_demos.list.columns[0].uiFlags = UI_LEFT; diff --git a/src/ui_local.h b/src/ui_local.h index 8b80f66..34826de 100644 --- a/src/ui_local.h +++ b/src/ui_local.h @@ -166,11 +166,10 @@ typedef struct menuSlider_s { #define MLIST_BORDER_WIDTH 1 #define MLIST_SCROLLBAR_WIDTH GENERIC_SPACING(CHAR_WIDTH) #define MLIST_PRESTEP 3 +#define MLIST_PADDING (MLIST_PRESTEP*2) -#define MLF_HIDE_SCROLLBAR (1<<0) -#define MLF_HIDE_SCROLLBAR_EMPTY (1<<1) -#define MLF_HIDE_BACKGROUND (1<<2) -#define MLF_HIDE_HEADER (1<<3) +#define MLF_HEADER 0x00000001 +#define MLF_SCROLLBAR 0x00000002 typedef struct menuListColumn_s { char *name; @@ -199,7 +198,7 @@ typedef struct menuList_s { int numcolumns; int sortdir, sortcol; - menuSound_t (*sort)(struct menuList_s *, int column); + menuSound_t (*sort)(struct menuList_s *); } menuList_t; typedef struct menuSpinControl_s { diff --git a/src/ui_menu.c b/src/ui_menu.c index a931620..02c0bd1 100644 --- a/src/ui_menu.c +++ b/src/ui_menu.c @@ -744,7 +744,7 @@ static void MenuList_ValidatePrestep(menuList_t *l) static void MenuList_AdjustPrestep(menuList_t *l) { - if (l->numItems > l->maxItems) { + if (l->numItems > l->maxItems && l->curvalue > 0) { if (l->prestep > l->curvalue) { l->prestep = l->curvalue; } else if (l->prestep < l->curvalue - l->maxItems + 1) { @@ -766,13 +766,13 @@ void MenuList_Init(menuList_t *l) int i; height = l->generic.height; - if (!(l->mlFlags & MLF_HIDE_HEADER)) { + if (l->mlFlags & MLF_HEADER) { height -= MLIST_SPACING; } l->maxItems = height / MLIST_SPACING; - clamp(l->curvalue, 0, l->numItems - 1); + //clamp(l->curvalue, 0, l->numItems - 1); MenuList_ValidatePrestep(l); @@ -784,14 +784,14 @@ void MenuList_Init(menuList_t *l) l->generic.rect.width += l->columns[i].width; } -// if( !( l->mlFlags & MLF_HIDE_SCROLLBAR ) ) { -// rc->width += MLIST_SCROLLBAR_WIDTH; -// } + if (l->mlFlags & MLF_SCROLLBAR) { + l->generic.rect.width += MLIST_SCROLLBAR_WIDTH; + } l->generic.rect.height = l->generic.height; if (l->sortdir && l->sort) { - l->sort(l, l->sortcol); + l->sort(l); } } @@ -814,7 +814,7 @@ void MenuList_SetValue(menuList_t *l, int value) MenuList_AdjustPrestep(l); } -static int MenuList_SetColumn(menuList_t *l, int value) +static menuSound_t MenuList_SetColumn(menuList_t *l, int value) { if (l->sortcol == value) { l->sortdir = -l->sortdir; @@ -823,18 +823,88 @@ static int MenuList_SetColumn(menuList_t *l, int value) l->sortdir = 1; } if (l->sort) { - l->sort(l, l->sortcol); + l->sort(l); } return QMS_SILENT; } +// finds a visible column by number, with numeration starting at 1 +static menuSound_t MenuList_FindColumn(menuList_t *l, int rel) +{ + int i, j; + + if (!l->sortdir) + return QMS_NOTHANDLED; + + for (i = 0, j = 0; i < l->numcolumns; i++) { + if (!l->columns[i].width) + continue; + + if (++j == rel) + return MenuList_SetColumn(l, i); + } + + return QMS_NOTHANDLED; +} + +static menuSound_t MenuList_PrevColumn(menuList_t *l) +{ + int col; + + if (!l->sortdir || !l->numcolumns) { + return QMS_NOTHANDLED; + } + + col = l->sortcol; + if (col < 0) + return MenuList_FindColumn(l, 1); + + do { + if (col < 0) { + col = l->numcolumns - 1; + } else { + col--; + } + if (col == l->sortcol) { + return QMS_SILENT; + } + } while (!l->columns[col].width); + + return MenuList_SetColumn(l, col); +} + +static menuSound_t MenuList_NextColumn(menuList_t *l) +{ + int col; + + if (!l->sortdir || !l->numcolumns) { + return QMS_NOTHANDLED; + } + + col = l->sortcol; + if (col < 0) + return MenuList_FindColumn(l, 1); + + do { + if (col == l->numcolumns - 1) { + col = 0; + } else { + col++; + } + if (col == l->sortcol) { + return QMS_SILENT; + } + } while (!l->columns[col].width); + + return MenuList_SetColumn(l, col); +} /* ================= MenuList_Click ================= */ -static int MenuList_Click(menuList_t *l) +static menuSound_t MenuList_Click(menuList_t *l) { int i, j; vrect_t rect; @@ -843,15 +913,62 @@ static int MenuList_Click(menuList_t *l) return QMS_SILENT; } + // click on scroll bar + if ((l->mlFlags & MLF_SCROLLBAR) && l->numItems > l->maxItems) { + int x = l->generic.rect.x + l->generic.rect.width - MLIST_SCROLLBAR_WIDTH; + int y = l->generic.rect.y + MLIST_SPACING; + int h = l->generic.height; + int barHeight; + float pageFrac, prestepFrac; + + if (l->mlFlags & MLF_HEADER) { + y += MLIST_SPACING; + h -= MLIST_SPACING; + } + + barHeight = h - MLIST_SPACING * 2; + pageFrac = (float)l->maxItems / l->numItems; + prestepFrac = (float)l->prestep / l->numItems; + + // click above thumb + rect.x = x; + rect.y = y; + rect.width = MLIST_SCROLLBAR_WIDTH; + rect.height = Q_rint(barHeight * prestepFrac); + if (UI_CursorInRect(&rect)) { + l->prestep -= l->maxItems; + MenuList_ValidatePrestep(l); + return QMS_MOVE; + } + + h = rect.height + Q_rint(barHeight * pageFrac); + + // click below thumb + rect.y = y + h; + rect.height = barHeight - h; + if (UI_CursorInRect(&rect)) { + l->prestep += l->maxItems; + MenuList_ValidatePrestep(l); + return QMS_MOVE; + } + } + rect.x = l->generic.rect.x; rect.y = l->generic.rect.y; rect.width = l->generic.rect.width; rect.height = MLIST_SPACING; + if (l->mlFlags & MLF_SCROLLBAR) { + rect.width -= MLIST_SCROLLBAR_WIDTH; + } + // click on header - if (!(l->mlFlags & MLF_HIDE_HEADER)) { + if (l->mlFlags & MLF_HEADER) { if (l->sortdir && UI_CursorInRect(&rect)) { for (j = 0; j < l->numcolumns; j++) { + if (!l->columns[j].width) { + continue; + } rect.width = l->columns[j].width; if (UI_CursorInRect(&rect)) { return MenuList_SetColumn(l, j); @@ -892,7 +1009,7 @@ static int MenuList_Click(menuList_t *l) MenuList_Key ================= */ -static int MenuList_Key(menuList_t *l, int key) +static menuSound_t MenuList_Key(menuList_t *l, int key) { //int i; @@ -901,11 +1018,7 @@ static int MenuList_Key(menuList_t *l, int key) } if (Key_IsDown(K_ALT) && Q_isdigit(key)) { - int col = key == '0' ? 9 : key - '0' - 1; - if (l->sortdir && col < l->numcolumns) { - return MenuList_SetColumn(l, col); - } - return QMS_NOTHANDLED; + return MenuList_FindColumn(l, key - '0'); } #if 0 @@ -946,25 +1059,18 @@ static int MenuList_Key(menuList_t *l, int key) switch (key) { case K_LEFTARROW: case 'h': - if (l->sortdir) { - if (l->sortcol > 0) { - return MenuList_SetColumn(l, l->sortcol - 1); - } - return MenuList_SetColumn(l, l->numcolumns - 1); - } - break; + return MenuList_PrevColumn(l); + case K_RIGHTARROW: case 'l': - if (l->sortdir) { - if (l->sortcol < l->numcolumns - 1) { - return MenuList_SetColumn(l, l->sortcol + 1); - } - return MenuList_SetColumn(l, 0); - } - break; + return MenuList_NextColumn(l); + case K_UPARROW: case K_KP_UPARROW: case 'k': + if (l->curvalue < 0) { + goto home; + } if (l->curvalue > 0) { l->curvalue--; if (l->generic.change) { @@ -978,6 +1084,9 @@ static int MenuList_Key(menuList_t *l, int key) case K_DOWNARROW: case K_KP_DOWNARROW: case 'j': + if (l->curvalue < 0) { + goto home; + } if (l->curvalue < l->numItems - 1) { l->curvalue++; if (l->generic.change) { @@ -990,6 +1099,7 @@ static int MenuList_Key(menuList_t *l, int key) case K_HOME: case K_KP_HOME: + home: l->prestep = 0; l->curvalue = 0; if (l->generic.change) { @@ -1028,15 +1138,39 @@ static int MenuList_Key(menuList_t *l, int key) case K_PGUP: case K_KP_PGUP: - l->prestep -= l->maxItems; - MenuList_ValidatePrestep(l); - return QMS_SILENT; + if (l->curvalue < 0) { + goto home; + } + if (l->curvalue > 0) { + l->curvalue -= l->maxItems - 1; + if (l->curvalue < 0) { + l->curvalue = 0; + } + if (l->generic.change) { + l->generic.change(&l->generic); + } + MenuList_AdjustPrestep(l); + return QMS_MOVE; + } + return QMS_BEEP; case K_PGDN: case K_KP_PGDN: - l->prestep += l->maxItems; - MenuList_ValidatePrestep(l); - return QMS_SILENT; + if (l->curvalue < 0) { + goto home; + } + if (l->curvalue < l->numItems - 1) { + l->curvalue += l->maxItems - 1; + if (l->curvalue > l->numItems - 1) { + l->curvalue = l->numItems - 1; + } + if (l->generic.change) { + l->generic.change(&l->generic); + } + MenuList_AdjustPrestep(l); + return QMS_MOVE; + } + return QMS_BEEP; case K_MOUSE1: case K_MOUSE2: @@ -1064,7 +1198,7 @@ static void MenuList_DrawString(int x, int y, int flags, rc.bottom = 0; if ((column->uiFlags & UI_CENTER) == UI_CENTER) { - x += column->width / 2; + x += column->width / 2 - 1; } else if (column->uiFlags & UI_RIGHT) { x += column->width - MLIST_PRESTEP; } else { @@ -1100,12 +1234,16 @@ static void MenuList_Draw(menuList_t *l) height = l->generic.rect.height; // draw header - if (!(l->mlFlags & MLF_HIDE_HEADER)) { + if (l->mlFlags & MLF_HEADER) { xx = x; for (j = 0; j < l->numcolumns; j++) { int flags = UI_ALTCOLOR; uint32_t color = uis.color.normal.u32; + if (!l->columns[j].width) { + continue; + } + if (l->sortcol == j && l->sortdir) { flags = 0; if (l->generic.flags & QMF_HASFOCUS) { @@ -1125,16 +1263,14 @@ static void MenuList_Draw(menuList_t *l) height -= MLIST_SPACING; } - if (!(l->mlFlags & MLF_HIDE_SCROLLBAR) && - (!(l->mlFlags & MLF_HIDE_SCROLLBAR_EMPTY) || l->numItems > l->maxItems)) { + if (l->mlFlags & MLF_SCROLLBAR) { barHeight = height - MLIST_SPACING * 2; yy = y + MLIST_SPACING; // draw scrollbar background - if (!(l->mlFlags & MLF_HIDE_BACKGROUND)) { - R_DrawFill32(x + width, yy, MLIST_SCROLLBAR_WIDTH - 1, - barHeight, uis.color.normal.u32); - } + R_DrawFill32(x + width - MLIST_SCROLLBAR_WIDTH, yy, + MLIST_SCROLLBAR_WIDTH - 1, barHeight, + uis.color.normal.u32); if (l->numItems > l->maxItems) { pageFrac = (float)l->maxItems / l->numItems; @@ -1145,17 +1281,22 @@ static void MenuList_Draw(menuList_t *l) } // draw scrollbar thumb - R_DrawFill32(x + width, + R_DrawFill32(x + width - MLIST_SCROLLBAR_WIDTH, yy + Q_rint(barHeight * prestepFrac), MLIST_SCROLLBAR_WIDTH - 1, Q_rint(barHeight * pageFrac), uis.color.selection.u32); } + // draw background xx = x; for (j = 0; j < l->numcolumns; j++) { uint32_t color = uis.color.normal.u32; + if (!l->columns[j].width) { + continue; + } + if (l->sortcol == j && l->sortdir) { if (l->generic.flags & QMF_HASFOCUS) { color = uis.color.active.u32; @@ -1174,6 +1315,9 @@ static void MenuList_Draw(menuList_t *l) if (!(l->generic.flags & QMF_DISABLED) && i == l->curvalue) { xx = x; for (j = 0; j < l->numcolumns; j++) { + if (!l->columns[j].width) { + continue; + } R_DrawFill32(xx, yy, l->columns[j].width - 1, MLIST_SPACING, uis.color.selection.u32); xx += l->columns[j].width; @@ -1188,9 +1332,10 @@ static void MenuList_Draw(menuList_t *l) break; } - MenuList_DrawString(xx, yy, 0, &l->columns[j], s); - - xx += l->columns[j].width; + if (l->columns[j].width) { + MenuList_DrawString(xx, yy, 0, &l->columns[j], s); + xx += l->columns[j].width; + } s += strlen(s) + 1; } @@ -1203,11 +1348,19 @@ void MenuList_Sort(menuList_t *l, int offset, int (*cmpfunc)(const void *, const void *n; int i; - if (!l->items) { + if (!l->items) + return; + + if (offset >= l->numItems) return; - } - n = l->items[l->curvalue]; + if (l->sortcol < 0 || l->sortcol >= l->numcolumns) + return; + + if (l->curvalue < 0 || l->curvalue >= l->numItems) + n = NULL; + else + n = l->items[l->curvalue]; qsort(l->items + offset, l->numItems - offset, sizeof(char *), cmpfunc); @@ -1218,7 +1371,8 @@ void MenuList_Sort(menuList_t *l, int offset, int (*cmpfunc)(const void *, const } } - MenuList_AdjustPrestep(l); + if (n) + MenuList_AdjustPrestep(l); } /* diff --git a/src/ui_multiplayer.c b/src/ui_multiplayer.c index 43434c4..a15d14b 100644 --- a/src/ui_multiplayer.c +++ b/src/ui_multiplayer.c @@ -414,6 +414,7 @@ void M_Menu_Servers(void) m_join.list.generic.change = Change; m_join.list.items = (void **)m_join.names; m_join.list.numcolumns = 3; + m_join.list.mlFlags = MLF_HEADER | MLF_SCROLLBAR; m_join.list.columns[0].uiFlags = UI_LEFT; m_join.list.columns[0].name = "Hostname"; @@ -428,6 +429,7 @@ void M_Menu_Servers(void) m_join.info.generic.type = MTYPE_LIST; m_join.info.generic.flags = QMF_LEFT_JUSTIFY | QMF_HIDDEN; m_join.info.numcolumns = 2; + m_join.info.mlFlags = MLF_HEADER | MLF_SCROLLBAR; m_join.info.columns[0].uiFlags = UI_LEFT; m_join.info.columns[0].name = "Key"; @@ -439,8 +441,8 @@ void M_Menu_Servers(void) // m_join.players.generic.type = MTYPE_LIST; m_join.players.generic.flags = QMF_LEFT_JUSTIFY | QMF_HIDDEN | QMF_DISABLED; - m_join.players.mlFlags = MLF_HIDE_SCROLLBAR; m_join.players.numcolumns = 3; + m_join.players.mlFlags = MLF_HEADER; m_join.players.columns[0].uiFlags = UI_CENTER; m_join.players.columns[0].name = "Frg"; |