]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into terencehill/menu_gametype_tooltips_2 243/head
authorterencehill <piuntn@gmail.com>
Wed, 21 Oct 2015 08:22:02 +0000 (10:22 +0200)
committerterencehill <piuntn@gmail.com>
Wed, 21 Oct 2015 08:22:02 +0000 (10:22 +0200)
qcsrc/common/mapinfo.qh
qcsrc/menu/item/listbox.qc
qcsrc/menu/menu.qc
qcsrc/menu/xonotic/dialog_settings_game.qc
qcsrc/menu/xonotic/dialog_settings_game_model.qc
qcsrc/menu/xonotic/gametypelist.qc

index 6faef6e05716be116e414e9db8615186f2b618e4..9c96c6823c8c2d75ab9a2df17c92b663ddfee9db 100644 (file)
@@ -54,49 +54,49 @@ int MAPINFO_TYPE_ALL;
 #define IS_GAMETYPE(NAME) \
     (MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME)
 
-REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"timelimit=20 pointlimit=30 leadlimit=0",_("Score as many frags as you can."));
+REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"timelimit=20 pointlimit=30 leadlimit=0",_("Score as many frags as you can"));
 #define g_dm IS_GAMETYPE(DEATHMATCH)
 
-REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,false,"timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left."));
+REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,false,"timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
 #define g_lms IS_GAMETYPE(LMS)
 
-REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,false,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line."));
+REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,false,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line"));
 #define g_race IS_GAMETYPE(RACE)
 
-REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,false,"timelimit=20 skill=-1",_("Race for fastest time."));
+REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,false,"timelimit=20 skill=-1",_("Race for fastest time"));
 #define g_cts IS_GAMETYPE(CTS)
 
-REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,true,"timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team."));
+REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,true,"timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team"));
 #define g_tdm IS_GAMETYPE(TEAM_DEATHMATCH)
 
-REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,true,"timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team."));
+REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,true,"timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team"));
 #define g_ctf IS_GAMETYPE(CTF)
 
-REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round."));
+REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round"));
 #define g_ca IS_GAMETYPE(CA)
 
-REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,true,"timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win."));
+REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,true,"timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win"));
 #define g_domination IS_GAMETYPE(DOMINATION)
 
-REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,true,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round."));
+REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,true,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round"));
 #define g_keyhunt IS_GAMETYPE(KEYHUNT)
 
-REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,true,"timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out."));
+REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,true,"timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out"));
 #define g_assault IS_GAMETYPE(ASSAULT)
 
-REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,true,"pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator."));
+REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,true,"pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator"));
 #define g_onslaught IS_GAMETYPE(ONSLAUGHT)
 
-REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,true,"timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean."));
+REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,true,"timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean"));
 #define g_nexball IS_GAMETYPE(NEXBALL)
 
-REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them, freeze the most enemies to win."));
+REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them, freeze the most enemies to win"));
 #define g_freezetag IS_GAMETYPE(FREEZETAG)
 
-REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,true,"timelimit=20 pointlimit=30",_("Hold the ball to get points for kills."));
+REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,true,"timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
 #define g_keepaway IS_GAMETYPE(KEEPAWAY)
 
-REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,false,"pointlimit=50 teams=0",_("Survive against waves of monsters."));
+REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,false,"pointlimit=50 teams=0",_("Survive against waves of monsters"));
 #define g_invasion IS_GAMETYPE(INVASION)
 
 const int MAPINFO_FEATURE_WEAPONS       = 1; // not defined for instagib-only maps
index 87f1719b4e14779f5abe809d1c39d8a9b1b52bd5..9210e14b384c90e262ece0be368b87e397cd1178 100644 (file)
@@ -14,6 +14,7 @@ CLASS(ListBox, Item)
        ATTRIB(ListBox, focusable, float, 1)
        ATTRIB(ListBox, focusedItem, int, -1)
        ATTRIB(ListBox, focusedItemAlpha, float, 0.3)
+       METHOD(ListBox, setFocusedItem, void(entity, int));
        ATTRIB(ListBox, mouseMoveOffset, float, -1) // let know where the cursor is when the list scrolls without moving the cursor
        ATTRIB(ListBox, allowFocusSound, float, 1)
        ATTRIB(ListBox, selectedItem, int, 0)
@@ -21,6 +22,7 @@ CLASS(ListBox, Item)
        ATTRIB(ListBox, origin, vector, '0 0 0')
        ATTRIB(ListBox, scrollPos, float, 0) // measured in window heights, fixed when needed
        ATTRIB(ListBox, scrollPosTarget, float, 0)
+       METHOD(ListBox, isScrolling, bool(entity));
        ATTRIB(ListBox, needScrollToItem, float, -1)
        METHOD(ListBox, scrollToItem, void(entity, int));
        ATTRIB(ListBox, previousValue, float, 0)
@@ -53,6 +55,7 @@ CLASS(ListBox, Item)
        METHOD(ListBox, clickListBoxItem, void(entity, float, vector)); // item number, relative clickpos
        METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)); // item number, relative clickpos
        METHOD(ListBox, setSelected, void(entity, float));
+       METHOD(ListBox, focusedItemChangeNotify, void(entity));
 
        METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float));
        METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float));
@@ -84,6 +87,11 @@ ENDCLASS(ListBox)
 #endif
 
 #ifdef IMPLEMENTATION
+bool ListBox_isScrolling(entity me)
+{
+       return (me.scrollPos != me.scrollPosTarget);
+}
+
 void ListBox_scrollToItem(entity me, int i)
 {
        // scroll doesn't work properly until itemHeight is set to the correct value
@@ -163,7 +171,7 @@ float ListBox_keyDown(entity me, float key, float ascii, float shift)
        }
        else if(key == K_MWHEELDOWN)
        {
-               me.scrollPosTarget = min(me.scrollPosTarget + 0.5, me.getTotalHeight(me) - 1);
+               me.scrollPosTarget = min(me.scrollPosTarget + 0.5, max(0, me.getTotalHeight(me) - 1));
        }
        else if(key == K_PGUP || key == K_KP_PGUP)
        {
@@ -246,7 +254,7 @@ float ListBox_mouseMove(entity me, vector pos)
                me.mouseMoveOffset = pos.y;
        else
        {
-               me.focusedItem = -1;
+               me.setFocusedItem(me, -1);
                me.mouseMoveOffset = -1;
        }
        return 1;
@@ -278,7 +286,7 @@ float ListBox_mouseDrag(entity me, vector pos)
        else if(me.pressed == 2)
        {
                me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
-               me.focusedItem = me.selectedItem;
+               me.setFocusedItem(me, me.selectedItem);
                me.mouseMoveOffset = -1;
        }
        return 1;
@@ -317,10 +325,21 @@ float ListBox_mousePress(entity me, vector pos)
                me.pressed = 2;
                // an item has been clicked. Select it, ...
                me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
-               me.focusedItem = me.selectedItem;
+               me.setFocusedItem(me, me.selectedItem);
        }
        return 1;
 }
+void ListBox_setFocusedItem(entity me, int item)
+{
+       float focusedItem_save = me.focusedItem;
+       me.focusedItem = (item < me.nItems) ? item : -1;
+       if(focusedItem_save != me.focusedItem)
+       {
+               me.focusedItemChangeNotify(me);
+               if(me.focusedItem >= 0)
+                       me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED;
+       }
+}
 float ListBox_mouseRelease(entity me, vector pos)
 {
        if(me.pressed == 1)
@@ -334,7 +353,7 @@ float ListBox_mouseRelease(entity me, vector pos)
                // item dragging mode
                // select current one one last time...
                me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
-               me.focusedItem = me.selectedItem;
+               me.setFocusedItem(me, me.selectedItem);
                // and give it a nice click event
                if(me.nItems > 0)
                {
@@ -358,7 +377,7 @@ void ListBox_focusLeave(entity me)
        // by a mouse click on an item of the list
        // for example showing a dialog on right click
        me.pressed = 0;
-       me.focusedItem = -1;
+       me.setFocusedItem(me, -1);
        me.mouseMoveOffset = -1;
 }
 void ListBox_updateControlTopBottom(entity me)
@@ -407,12 +426,8 @@ void ListBox_draw(entity me)
        vector oldshift, oldscale;
 
        // we can't do this in mouseMove as the list can scroll without moving the cursor
-       float focusedItem_save = me.focusedItem;
        if(me.mouseMoveOffset != -1)
-               me.focusedItem = me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset);
-       if(me.focusedItem >= 0)
-       if(focusedItem_save != me.focusedItem)
-               me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED;
+               me.setFocusedItem(me, me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset));
 
        if(me.needScrollToItem >= 0)
        {
@@ -476,6 +491,10 @@ void ListBox_draw(entity me)
        SUPER(ListBox).draw(me);
 }
 
+void ListBox_focusedItemChangeNotify(entity me)
+{
+}
+
 void ListBox_clickListBoxItem(entity me, float i, vector where)
 {
        // template method
index fde2c3c1eb7594125c82cb2cac15eb99ae68284d..8f522d42da5779049ca5ce5f79f27ceeddd543f0 100644 (file)
@@ -407,7 +407,7 @@ vector menuTooltipOrigin;
 vector menuTooltipSize;
 float menuTooltipAlpha;
 string menuTooltipText;
-float menuTooltipState; // 0: static, 1: fading in, 2: fading out
+float menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
 float m_testmousetooltipbox(vector pos)
 {
        if(pos.x >= menuTooltipOrigin.x && pos.x < menuTooltipOrigin.x + menuTooltipSize.x)
@@ -534,6 +534,7 @@ string gettooltip()
        }
        return menuTooltipItem.tooltip;
 }
+string prev_tooltip;
 void m_tooltip(vector pos)
 {
        float f, i, w;
@@ -556,13 +557,30 @@ void m_tooltip(vector pos)
                menuTooltipAveragedMousePos = menuTooltipAveragedMousePos * (1 - f) + pos * f;
                f = vlen(pos - menuTooltipAveragedMousePos);
                if(f < 0.01)
+               {
                        it = m_findtooltipitem(main, pos);
+
+                       if(it.instanceOfListBox && it.isScrolling(it))
+                               it = world;
+
+                       if(it && prev_tooltip != it.tooltip)
+                       {
+                               // fade out if tooltip of a certain item has changed
+                               menuTooltipState = 3;
+                               if(prev_tooltip)
+                                       strunzone(prev_tooltip);
+                               prev_tooltip = strzone(it.tooltip);
+                       }
+                       else if(menuTooltipItem && !m_testmousetooltipbox(pos))
+                               menuTooltipState = 3; // fade out if mouse touches it
+
+               }
                else
                        it = NULL;
        }
        fontsize = '1 0 0' * (SKINFONTSIZE_TOOLTIP / conwidth) + '0 1 0' * (SKINFONTSIZE_TOOLTIP / conheight);
 
-       // float menuTooltipState; // 0: static, 1: fading in, 2: fading out
+       // float menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
        if(it != menuTooltipItem)
        {
                switch(menuTooltipState)
@@ -613,18 +631,15 @@ void m_tooltip(vector pos)
        else if(menuTooltipState == 2) // re-fade in?
                menuTooltipState = 1;
 
-       if(menuTooltipItem)
-               if(!m_testmousetooltipbox(pos))
-                       menuTooltipState = 2; // fade out if mouse touches it
-
        switch(menuTooltipState)
        {
-               case 1:
+               case 1: // fade in
                        menuTooltipAlpha = bound(0, menuTooltipAlpha + 5 * frametime, 1);
                        if(menuTooltipAlpha == 1)
                                menuTooltipState = 0;
                        break;
-               case 2:
+               case 2: // fade out
+               case 3: // forced fade out
                        menuTooltipAlpha = bound(0, menuTooltipAlpha - 2 * frametime, 1);
                        if(menuTooltipAlpha == 0)
                        {
index 69ab6758226e19356fd8d9cd459c93dcd5f6ebe7..3c1503b29774472af5b256b37930c7736c454d81 100644 (file)
@@ -12,6 +12,13 @@ CLASS(SettingSource, DataSource)
         if (returns) returns(it.title, string_null);
         return it;
     }
+    METHOD(SettingSource, getEntryTooltip, entity(entity this, int i, void(string theTooltip) returns))
+    {
+        Lazy l = Settings[i];
+        entity it = l.m_get();
+        if (returns) returns(it.tooltip);
+        return it;
+    }
     METHOD(SettingSource, reload, int(entity this, string filter)) { return Settings_COUNT; }
 ENDCLASS(SettingSource)
 
@@ -30,15 +37,23 @@ CLASS(XonoticRegisteredSettingsList, XonoticListBox)
     ATTRIB(XonoticRegisteredSettingsList, source, DataSource, NULL)
        ATTRIB(XonoticRegisteredSettingsList, onChange, void(entity, entity), func_null)
        ATTRIB(XonoticRegisteredSettingsList, onChangeEntity, entity, NULL)
+       METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity));
+
        string XonoticRegisteredSettingsList_cb_name;
-       void XonoticRegisteredSettingsList_cb(string _name, string _icon)
+       string XonoticRegisteredSettingsList_cb_tooltip;
+       void XonoticRegisteredSettingsList_getNameIcon_cb(string _name, string _icon)
        {
                XonoticRegisteredSettingsList_cb_name = _name;
        }
+       void XonoticRegisteredSettingsList_getTooltip_cb(string _tooltip)
+       {
+               XonoticRegisteredSettingsList_cb_tooltip = _tooltip;
+       }
+
        METHOD(XonoticRegisteredSettingsList, drawListBoxItem, void(entity this, int i, vector absSize, bool isSelected, bool isFocused))
        {
                if (!this.source) return;
-               if (!this.source.getEntry(this.source, i, XonoticRegisteredSettingsList_cb)) return;
+               if (!this.source.getEntry(this.source, i, XonoticRegisteredSettingsList_getNameIcon_cb)) return;
                string name = XonoticRegisteredSettingsList_cb_name;
                if (isSelected) {
                        draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
@@ -49,6 +64,26 @@ CLASS(XonoticRegisteredSettingsList, XonoticListBox)
                string s = draw_TextShortenToWidth(strdecolorize(name), 1, 0, this.realFontSize);
                draw_Text(this.realUpperMargin * eY + (0.5 * this.realFontSize.x) * eX, s, this.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
        }
+
+       METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity this))
+       {
+               if (this.focusedItem == -1 || !this.source)
+               {
+                       clearTooltip(this);
+                       return;
+               }
+               if (!this.source.getEntryTooltip(this, this.focusedItem, XonoticRegisteredSettingsList_getTooltip_cb))
+               {
+                       clearTooltip(this);
+                       return;
+               }
+               string theTooltip = XonoticRegisteredSettingsList_cb_tooltip;
+               if(theTooltip != "")
+                       setZonedTooltip(this, theTooltip, string_null);
+               else
+                       clearTooltip(this);
+       }
+
        METHOD(XonoticRegisteredSettingsList, refilter, void(entity this))
        {
                if (!this.source) {
index 7b0794bdd782e671c84693eb6b60b715dbba2b48..45d7aee3048bd743f2cf018cd64d5643b3ec1859 100644 (file)
@@ -5,6 +5,7 @@ CLASS(XonoticGameModelSettingsTab, XonoticTab)
        METHOD(XonoticGameModelSettingsTab, fill, void(entity));
        METHOD(XonoticGameModelSettingsTab, showNotify, void(entity));
        ATTRIB(XonoticGameModelSettingsTab, title, string, _("Models"))
+       ATTRIB(XonoticGameModelSettingsTab, tooltip, string, _("Customize how players and items are displayed in game"))
        ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticGameModelSettingsTab, rows, float, 13)
        ATTRIB(XonoticGameModelSettingsTab, columns, float, 5)
index e2fdfa8e72b60e52881c621e77f57379080c5c99..5522e13c7f75f4fd81302e3af353c5f94e370a44 100644 (file)
@@ -11,6 +11,7 @@ CLASS(XonoticGametypeList, XonoticListBox)
        METHOD(XonoticGametypeList, saveCvars, void(entity));
        METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float));
        METHOD(XonoticGametypeList, clickListBoxItem, void(entity, float, vector));
+       METHOD(XonoticGametypeList, focusedItemChangeNotify, void(entity));
 
        ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0')
        ATTRIB(XonoticGametypeList, realUpperMargin, float, 0)
@@ -137,4 +138,11 @@ void XonoticGametypeList_clickListBoxItem(entity me, float i, vector where)
 {
        m_play_click_sound(MENU_SOUND_SELECT);
 }
+void XonoticGametypeList_focusedItemChangeNotify(entity me)
+{
+       if(me.focusedItem >= 0)
+               setZonedTooltip(me, MapInfo_Type_Description(GameType_GetID(me.focusedItem)), string_null);
+       else
+               clearTooltip(me);
+}
 #endif