diff options
author | Andrey Nazarov <skuller@skuller.net> | 2013-01-27 19:24:24 +0400 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2013-01-27 19:24:24 +0400 |
commit | d72fde683f81a13fc7bdf5fbd0838d350627ef9b (patch) | |
tree | ba20231d2361f5bd76178de8fcd1cb7dcc163c04 | |
parent | 6b47375923a45f09ad246a4dc3664e48dd15af42 (diff) |
Scroll menu list by dragging mouse.
-rw-r--r-- | inc/client/ui.h | 4 | ||||
-rw-r--r-- | src/client/keys.c | 9 | ||||
-rw-r--r-- | src/client/ui/menu.c | 69 | ||||
-rw-r--r-- | src/client/ui/ui.c | 22 | ||||
-rw-r--r-- | src/client/ui/ui.h | 3 |
5 files changed, 92 insertions, 15 deletions
diff --git a/inc/client/ui.h b/inc/client/ui.h index 053ea05..2752733 100644 --- a/inc/client/ui.h +++ b/inc/client/ui.h @@ -33,7 +33,7 @@ typedef enum { void UI_Init(void); void UI_Shutdown(void); void UI_ModeChanged(void); -void UI_Keydown(int key); +void UI_KeyEvent(int key, qboolean down); void UI_CharEvent(int key); void UI_Draw(int realtime); void UI_OpenMenu(uiMenu_t menu); @@ -46,7 +46,7 @@ qboolean UI_IsTransparent(void); #define UI_Init() (void)0 #define UI_Shutdown() (void)0 #define UI_ModeChanged() (void)0 -#define UI_Keydown(key) (void)0 +#define UI_KeyEvent(key, down) (void)0 #define UI_CharEvent(key) (void)0 #define UI_Draw(realtime) (void)0 #define UI_OpenMenu(menu) (void)0 diff --git a/src/client/keys.c b/src/client/keys.c index a13c3e1..892cf1a 100644 --- a/src/client/keys.c +++ b/src/client/keys.c @@ -684,7 +684,7 @@ void Key_Event(unsigned key, qboolean down, unsigned time) Con_Close(qtrue); } } else if (cls.key_dest & KEY_MENU) { - UI_Keydown(key); + UI_KeyEvent(key, down); } else if (cls.key_dest & KEY_MESSAGE) { Key_Message(key); } else if (cls.state >= ca_active) { @@ -765,13 +765,16 @@ void Key_Event(unsigned key, qboolean down, unsigned time) if (cls.key_dest == KEY_GAME) return; - if (!down) + if (!down) { + if (cls.key_dest & KEY_MENU) + UI_KeyEvent(key, down); return; // other subsystems only care about key down events + } if (cls.key_dest & KEY_CONSOLE) { Key_Console(key); } else if (cls.key_dest & KEY_MENU) { - UI_Keydown(key); + UI_KeyEvent(key, down); } else if (cls.key_dest & KEY_MESSAGE) { Key_Message(key); } diff --git a/src/client/ui/menu.c b/src/client/ui/menu.c index ffd2f36..d3b4e9c 100644 --- a/src/client/ui/menu.c +++ b/src/client/ui/menu.c @@ -923,7 +923,7 @@ static menuSound_t MenuList_Click(menuList_t *l) 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; + int barHeight, pageHeight, prestepHeight; float pageFrac, prestepFrac; if (l->mlFlags & MLF_HEADER) { @@ -935,27 +935,55 @@ static menuSound_t MenuList_Click(menuList_t *l) pageFrac = (float)l->maxItems / l->numItems; prestepFrac = (float)l->prestep / l->numItems; + pageHeight = Q_rint(barHeight * pageFrac); + prestepHeight = Q_rint(barHeight * prestepFrac); + // click above thumb rect.x = x; rect.y = y; rect.width = MLIST_SCROLLBAR_WIDTH; - rect.height = Q_rint(barHeight * prestepFrac); + rect.height = prestepHeight; if (UI_CursorInRect(&rect)) { l->prestep -= l->maxItems; MenuList_ValidatePrestep(l); return QMS_MOVE; } - h = rect.height + Q_rint(barHeight * pageFrac); + // click on thumb + rect.y = y + prestepHeight; + rect.height = pageHeight; + if (UI_CursorInRect(&rect)) { + l->drag_y = uis.mouseCoords[1] - rect.y; + uis.mouseTracker = &l->generic; + return QMS_SILENT; + } // click below thumb - rect.y = y + h; - rect.height = barHeight - h; + rect.y = y + prestepHeight + pageHeight; + rect.height = barHeight - prestepHeight - pageHeight; if (UI_CursorInRect(&rect)) { l->prestep += l->maxItems; MenuList_ValidatePrestep(l); return QMS_MOVE; } + + // click above scrollbar + rect.y = y - MLIST_SPACING; + rect.height = MLIST_SPACING; + if (UI_CursorInRect(&rect)) { + l->prestep--; + MenuList_ValidatePrestep(l); + return QMS_MOVE; + } + + // click below scrollbar + rect.y = l->generic.rect.y + l->generic.height - MLIST_SPACING; + rect.height = MLIST_SPACING; + if (UI_CursorInRect(&rect)) { + l->prestep++; + MenuList_ValidatePrestep(l); + return QMS_MOVE; + } } rect.x = l->generic.rect.x; @@ -1186,6 +1214,30 @@ static menuSound_t MenuList_Key(menuList_t *l, int key) return QMS_NOTHANDLED; } +static menuSound_t MenuList_MouseMove(menuList_t *l) +{ + int y, h, barHeight; + + if (uis.mouseTracker != &l->generic) + return QMS_NOTHANDLED; + + y = l->generic.y + MLIST_SPACING; + h = l->generic.height; + + if (l->mlFlags & MLF_HEADER) { + y += MLIST_SPACING; + h -= MLIST_SPACING; + } + + barHeight = h - MLIST_SPACING * 2; + if (barHeight > 0) { + l->prestep = (uis.mouseCoords[1] - y - l->drag_y) * l->numItems / barHeight; + MenuList_ValidatePrestep(l); + } + + return QMS_SILENT; +} + /* ================= MenuList_DrawString @@ -2095,7 +2147,12 @@ menuSound_t Menu_CharEvent(menuCommon_t *item, int key) menuSound_t Menu_MouseMove(menuCommon_t *item) { - return QMS_NOTHANDLED; + switch (item->type) { + case MTYPE_LIST: + return MenuList_MouseMove((menuList_t *)item); + default: + return QMS_NOTHANDLED; + } } static menuSound_t Menu_DefaultKey(menuFrameWork_t *m, int key) diff --git a/src/client/ui/ui.c b/src/client/ui/ui.c index 29da482..89c3fd9 100644 --- a/src/client/ui/ui.c +++ b/src/client/ui/ui.c @@ -142,6 +142,7 @@ void UI_ForceMenuOff(void) Key_SetDest(Key_GetDest() & ~KEY_MENU); uis.menuDepth = 0; uis.activeMenu = NULL; + uis.mouseTracker = NULL; uis.transparent = qfalse; } @@ -169,6 +170,7 @@ void UI_PopMenu(void) } uis.activeMenu = uis.layers[uis.menuDepth - 1]; + uis.mouseTracker = NULL; uis.transparent = qfalse; for (i = uis.menuDepth - 1; i >= 0; i--) { @@ -384,9 +386,14 @@ qboolean UI_DoHitTest(void) return qfalse; } - if (!(item = Menu_HitTest(uis.activeMenu))) { - return qfalse; + if (uis.mouseTracker) { + item = uis.mouseTracker; + } else { + if (!(item = Menu_HitTest(uis.activeMenu))) { + return qfalse; + } } + if (!UI_IsItemSelectable(item)) { return qfalse; } @@ -511,10 +518,10 @@ void UI_StartSound(menuSound_t sound) /* ================= -UI_Keydown +UI_KeyEvent ================= */ -void UI_Keydown(int key) +void UI_KeyEvent(int key, qboolean down) { menuSound_t sound; @@ -522,6 +529,13 @@ void UI_Keydown(int key) return; } + if (!down) { + if (key == K_MOUSE1) { + uis.mouseTracker = NULL; + } + return; + } + sound = Menu_Keydown(uis.activeMenu, key); UI_StartSound(sound); diff --git a/src/client/ui/ui.h b/src/client/ui/ui.h index 7b80331..0c5e8f6 100644 --- a/src/client/ui/ui.h +++ b/src/client/ui/ui.h @@ -198,6 +198,8 @@ typedef struct menuList_s { int scratchCount; int scratchTime; + int drag_y; + menuListColumn_t columns[MAX_COLUMNS]; int numcolumns; int sortdir, sortcol; @@ -273,6 +275,7 @@ typedef struct uiStatic_s { int menuDepth; menuFrameWork_t *layers[MAX_MENU_DEPTH]; menuFrameWork_t *activeMenu; + menuCommon_t *mouseTracker; int mouseCoords[2]; qboolean entersound; // play after drawing a frame, so caching // won't disrupt the sound |