mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-07-04 05:55:47 -07:00
Get the index of the hovered element in GUI lists and use it to display item-specific tooltips in the gamesetup for the victory condition, maptype and starting resources.
Differential Revision: https://code.wildfiregames.com/D316 Fixes #3699 Patch By: Vladislav This was SVN commit r19588.
This commit is contained in:
parent
aa302dcb2d
commit
2599d0374e
4 changed files with 100 additions and 54 deletions
|
|
@ -186,15 +186,18 @@ function loadMapTypes()
|
|||
{
|
||||
"Name": "skirmish",
|
||||
"Title": translateWithContext("map", "Skirmish"),
|
||||
"Description": translate("A map with a predefined landscape and number of players. Freely select the other gamesettings."),
|
||||
"Default": true
|
||||
},
|
||||
{
|
||||
"Name": "random",
|
||||
"Title": translateWithContext("map", "Random")
|
||||
"Title": translateWithContext("map", "Random"),
|
||||
"Description": translate("Create a unique map with a different resource distribution each time. Freely chose the number of players and teams.")
|
||||
},
|
||||
{
|
||||
"Name": "scenario",
|
||||
"Title": translateWithContext("map", "Scenario")
|
||||
"Title": translateWithContext("map", "Scenario"),
|
||||
"Description": translate("A map with a predefined landscape and matchsettings.")
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ var g_OptionOrderInit = {
|
|||
*
|
||||
* GUI
|
||||
* title - The caption shown in the label.
|
||||
* tooltip - A description shown when hovering the option.
|
||||
* tooltip - A description shown when hovering the dropdown or a specific item.
|
||||
* labels - Array of translated strings selectable for this dropdown.
|
||||
* colors - Optional array of colors to tint the according dropdown items with.
|
||||
* hidden - If hidden, both the label and dropdown won't be visible. (default: false)
|
||||
|
|
@ -369,7 +369,7 @@ var g_OptionOrderInit = {
|
|||
var g_Dropdowns = {
|
||||
"mapType": {
|
||||
"title": () => translate("Map Type"),
|
||||
"tooltip": () => translate("Select a map type."),
|
||||
"tooltip": (hoverIdx) => g_MapTypes.Description[hoverIdx] || translate("Select a map type."),
|
||||
"labels": () => g_MapTypes.Title,
|
||||
"ids": () => g_MapTypes.Name,
|
||||
"default": () => g_MapTypes.Default,
|
||||
|
|
@ -392,7 +392,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"mapFilter": {
|
||||
"title": () => translate("Map Filter"),
|
||||
"tooltip": () => translate("Select a map filter."),
|
||||
"tooltip": (hoverIdx) => translate("Select a map filter."),
|
||||
"labels": () => g_MapFilterList.name,
|
||||
"ids": () => g_MapFilterList.id,
|
||||
"default": () => g_MapFilterList.Default,
|
||||
|
|
@ -407,7 +407,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"mapSelection": {
|
||||
"title": () => translate("Select Map"),
|
||||
"tooltip": () => translate("Select a map to play on."),
|
||||
"tooltip": (hoverIdx) => translate("Select a map to play on."),
|
||||
"labels": () => g_MapSelectionList.name,
|
||||
"colors": () => g_MapSelectionList.color,
|
||||
"ids": () => g_MapSelectionList.file,
|
||||
|
|
@ -421,7 +421,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"mapSize": {
|
||||
"title": () => translate("Map Size"),
|
||||
"tooltip": () => translate("Select map size. (Larger sizes may reduce performance.)"),
|
||||
"tooltip": (hoverIdx) => translate("Select map size. (Larger sizes may reduce performance.)"),
|
||||
"labels": () => g_MapSizes.Name,
|
||||
"ids": () => g_MapSizes.Tiles,
|
||||
"default": () => g_MapSizes.Default,
|
||||
|
|
@ -435,7 +435,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"numPlayers": {
|
||||
"title": () => translate("Number of Players"),
|
||||
"tooltip": () => translate("Select number of players."),
|
||||
"tooltip": (hoverIdx) => translate("Select number of players."),
|
||||
"labels": () => g_NumPlayersList,
|
||||
"ids": () => g_NumPlayersList,
|
||||
"default": () => g_MaxPlayers - 1,
|
||||
|
|
@ -455,7 +455,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"populationCap": {
|
||||
"title": () => translate("Population Cap"),
|
||||
"tooltip": () => translate("Select population cap."),
|
||||
"tooltip": (hoverIdx) => translate("Select population cap."),
|
||||
"labels": () => g_PopulationCapacities.Title,
|
||||
"ids": () => g_PopulationCapacities.Population,
|
||||
"default": () => g_PopulationCapacities.Default,
|
||||
|
|
@ -468,7 +468,13 @@ var g_Dropdowns = {
|
|||
},
|
||||
"startingResources": {
|
||||
"title": () => translate("Starting Resources"),
|
||||
"tooltip": () => translate("Select the game's starting resources."),
|
||||
"tooltip": (hoverIdx) => {
|
||||
return hoverIdx >= 0 ?
|
||||
sprintf(translate("Initial amount of each resource: %(resources)s."), {
|
||||
"resources": g_StartingResources.Resources[hoverIdx]
|
||||
}) :
|
||||
translate("Select the game's starting resources.");
|
||||
},
|
||||
"labels": () => g_StartingResources.Title,
|
||||
"ids": () => g_StartingResources.Resources,
|
||||
"default": () => g_StartingResources.Default,
|
||||
|
|
@ -482,7 +488,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"ceasefire": {
|
||||
"title": () => translate("Ceasefire"),
|
||||
"tooltip": () => translate("Set time where no attacks are possible."),
|
||||
"tooltip": (hoverIdx) => translate("Set time where no attacks are possible."),
|
||||
"labels": () => g_Ceasefire.Title,
|
||||
"ids": () => g_Ceasefire.Duration,
|
||||
"default": () => g_Ceasefire.Default,
|
||||
|
|
@ -495,7 +501,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"victoryCondition": {
|
||||
"title": () => translate("Victory Condition"),
|
||||
"tooltip": () => translate("Select victory condition."),
|
||||
"tooltip": (hoverIdx) => g_VictoryConditions.Description[hoverIdx] || translate("Select victory condition."),
|
||||
"labels": () => g_VictoryConditions.Title,
|
||||
"ids": () => g_VictoryConditions.Name,
|
||||
"default": () => g_VictoryConditions.Default,
|
||||
|
|
@ -510,7 +516,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"relicCount": {
|
||||
"title": () => translate("Relic Count"),
|
||||
"tooltip": () => translate("Total number of relics spawned on the map."),
|
||||
"tooltip": (hoverIdx) => translate("Total number of relics spawned on the map."),
|
||||
"labels": () => g_RelicCountList,
|
||||
"ids": () => g_RelicCountList,
|
||||
"default": () => g_RelicCountList.indexOf(5),
|
||||
|
|
@ -524,7 +530,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"victoryDuration": {
|
||||
"title": () => translate("Victory Duration"),
|
||||
"tooltip": () => translate("Number of minutes until the player has won."),
|
||||
"tooltip": (hoverIdx) => translate("Number of minutes until the player has won."),
|
||||
"labels": () => g_VictoryDurations.Title,
|
||||
"ids": () => g_VictoryDurations.Duration,
|
||||
"default": () => g_VictoryDurations.Default,
|
||||
|
|
@ -540,7 +546,7 @@ var g_Dropdowns = {
|
|||
},
|
||||
"gameSpeed": {
|
||||
"title": () => translate("Game Speed"),
|
||||
"tooltip": () => translate("Select game speed."),
|
||||
"tooltip": (hoverIdx) => translate("Select game speed."),
|
||||
"labels": () => g_GameSpeeds.Title,
|
||||
"ids": () => g_GameSpeeds.Speed,
|
||||
"default": () => g_GameSpeeds.Default,
|
||||
|
|
@ -777,7 +783,7 @@ var g_MiscControls = {
|
|||
"startGame": {
|
||||
"caption": () =>
|
||||
g_IsController ? translate("Start game!") : g_ReadyData[g_IsReady].caption,
|
||||
"tooltip": () =>
|
||||
"tooltip": (hoverIdx) =>
|
||||
!g_IsController ?
|
||||
g_ReadyData[g_IsReady].tooltip :
|
||||
!g_IsNetworked || Object.keys(g_PlayerAssignments).every(guid =>
|
||||
|
|
@ -1005,6 +1011,11 @@ function initDropdown(name, idx)
|
|||
supplementDefaults();
|
||||
updateGameAttributes();
|
||||
};
|
||||
|
||||
if (data.tooltip)
|
||||
dropdown.onHoverChange = function() {
|
||||
this.tooltip = data.tooltip(this.hovered);
|
||||
};
|
||||
}
|
||||
|
||||
function initPlayerDropdowns(name)
|
||||
|
|
|
|||
|
|
@ -45,16 +45,17 @@ CList::CList()
|
|||
AddSetting(GUIST_CColor, "textcolor");
|
||||
AddSetting(GUIST_CColor, "textcolor_selected");
|
||||
AddSetting(GUIST_int, "selected"); // Index selected. -1 is none.
|
||||
AddSetting(GUIST_int, "hovered");
|
||||
AddSetting(GUIST_CStrW, "tooltip");
|
||||
AddSetting(GUIST_CStr, "tooltip_style");
|
||||
|
||||
// Each list item has both a name (in 'list') and an associated data string (in 'list_data')
|
||||
AddSetting(GUIST_CGUIList, "list");
|
||||
AddSetting(GUIST_CGUIList, "list_data"); // TODO: this should be a list of raw strings, not of CGUIStrings
|
||||
|
||||
GUI<bool>::SetSetting(this, "scrollbar", false);
|
||||
|
||||
// Nothing is selected as default.
|
||||
GUI<int>::SetSetting(this, "selected", -1);
|
||||
GUI<int>::SetSetting(this, "hovered", -1);
|
||||
|
||||
// Add scroll-bar
|
||||
CGUIScrollBarVertical* bar = new CGUIScrollBarVertical();
|
||||
|
|
@ -194,45 +195,46 @@ void CList::HandleMessage(SGUIMessage& Message)
|
|||
break;
|
||||
}
|
||||
|
||||
bool scrollbar;
|
||||
CGUIList* pList;
|
||||
GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
|
||||
GUI<CGUIList>::GetSettingPointer(this, "list", pList);
|
||||
float scroll = 0.f;
|
||||
if (scrollbar)
|
||||
scroll = GetScrollBar(0).GetPos();
|
||||
int hovered = GetHoveredItem();
|
||||
if (hovered == -1)
|
||||
break;
|
||||
GUI<int>::SetSetting(this, "selected", hovered);
|
||||
UpdateAutoScroll();
|
||||
|
||||
CRect rect = GetListRect();
|
||||
CPos mouse = GetMousePos();
|
||||
mouse.y += scroll;
|
||||
int set = -1;
|
||||
for (int i = 0; i < (int)pList->m_Items.size(); ++i)
|
||||
{
|
||||
if (mouse.y >= rect.top + m_ItemsYPositions[i] &&
|
||||
mouse.y < rect.top + m_ItemsYPositions[i+1] &&
|
||||
// mouse is not over scroll-bar
|
||||
(!scrollbar || !GetScrollBar(0).IsVisible() ||
|
||||
mouse.x < GetScrollBar(0).GetOuterRect().left ||
|
||||
mouse.x > GetScrollBar(0).GetOuterRect().right))
|
||||
{
|
||||
set = i;
|
||||
}
|
||||
}
|
||||
CStrW soundPath;
|
||||
if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_selected", soundPath) == PSRETURN_OK && !soundPath.empty())
|
||||
g_SoundManager->PlayAsUI(soundPath.c_str(), false);
|
||||
|
||||
if (set != -1)
|
||||
{
|
||||
GUI<int>::SetSetting(this, "selected", set);
|
||||
UpdateAutoScroll();
|
||||
if (timer_Time() - m_LastItemClickTime < SELECT_DBLCLICK_RATE && hovered == m_PrevSelectedItem)
|
||||
this->SendEvent(GUIM_MOUSE_DBLCLICK_LEFT_ITEM, "mouseleftdoubleclickitem");
|
||||
m_LastItemClickTime = timer_Time();
|
||||
m_PrevSelectedItem = hovered;
|
||||
break;
|
||||
}
|
||||
|
||||
CStrW soundPath;
|
||||
if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_selected", soundPath) == PSRETURN_OK && !soundPath.empty())
|
||||
g_SoundManager->PlayAsUI(soundPath.c_str(), false);
|
||||
case GUIM_MOUSE_LEAVE:
|
||||
{
|
||||
int hoveredSetting = -1;
|
||||
GUI<int>::GetSetting(this, "hovered", hoveredSetting);
|
||||
if (hoveredSetting == -1)
|
||||
break;
|
||||
|
||||
if (timer_Time() - m_LastItemClickTime < SELECT_DBLCLICK_RATE && set == m_PrevSelectedItem)
|
||||
this->SendEvent(GUIM_MOUSE_DBLCLICK_LEFT_ITEM, "mouseleftdoubleclickitem");
|
||||
m_LastItemClickTime = timer_Time();
|
||||
m_PrevSelectedItem = set;
|
||||
}
|
||||
GUI<int>::SetSetting(this, "hovered", -1);
|
||||
ScriptEvent("hoverchange");
|
||||
break;
|
||||
}
|
||||
|
||||
case GUIM_MOUSE_OVER:
|
||||
{
|
||||
int hoveredSetting = -1;
|
||||
GUI<int>::GetSetting(this, "hovered", hoveredSetting);
|
||||
|
||||
int hovered = GetHoveredItem();
|
||||
if (hovered == hoveredSetting)
|
||||
break;
|
||||
|
||||
GUI<int>::SetSetting(this, "hovered", hovered);
|
||||
ScriptEvent("hoverchange");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -515,3 +517,31 @@ void CList::UpdateAutoScroll()
|
|||
if (m_ItemsYPositions[selected+1]-rect.GetHeight() > scroll)
|
||||
GetScrollBar(0).SetPos(m_ItemsYPositions[selected+1]-rect.GetHeight());
|
||||
}
|
||||
|
||||
int CList::GetHoveredItem()
|
||||
{
|
||||
bool scrollbar;
|
||||
CGUIList* pList;
|
||||
GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
|
||||
GUI<CGUIList>::GetSettingPointer(this, "list", pList);
|
||||
float scroll = 0.f;
|
||||
if (scrollbar)
|
||||
scroll = GetScrollBar(0).GetPos();
|
||||
|
||||
CRect rect = GetListRect();
|
||||
CPos mouse = GetMousePos();
|
||||
mouse.y += scroll;
|
||||
|
||||
// Mouse is over scrollbar
|
||||
if (scrollbar && GetScrollBar(0).IsVisible() &&
|
||||
mouse.x >= GetScrollBar(0).GetOuterRect().left &&
|
||||
mouse.x <= GetScrollBar(0).GetOuterRect().right)
|
||||
return -1;
|
||||
|
||||
for (size_t i = 0; i < pList->m_Items.size(); ++i)
|
||||
if (mouse.y >= rect.top + m_ItemsYPositions[i] &&
|
||||
mouse.y < rect.top + m_ItemsYPositions[i + 1])
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2015 Wildfire Games.
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -105,6 +105,8 @@ protected:
|
|||
*/
|
||||
std::vector<float> m_ItemsYPositions;
|
||||
|
||||
virtual int GetHoveredItem();
|
||||
|
||||
private:
|
||||
// Whether the list's items have been modified since last handling a message.
|
||||
bool m_Modified;
|
||||
|
|
|
|||
Loading…
Reference in a new issue