gui: support conditions for listbox items

Change-Id: Iea189ac53ec3d7c1bea83da7b77684778b1c0f46
This commit is contained in:
that
2015-09-13 23:00:54 +02:00
committed by Ethan Yonker
parent 20fb95d0a7
commit 8ab5c13428
2 changed files with 72 additions and 67 deletions
+68 -65
View File
@@ -58,45 +58,41 @@ GUIListBox::GUIListBox(xml_node<>* node) : GUIScrollList(node)
DataManager::GetValue(mVariable, currentValue);
}
else
allowSelection = false; // allows using listbox as a read-only list
allowSelection = false; // allows using listbox as a read-only list or menu
// Get the data for the list
child = FindNode(node, "listitem");
if (!child) return;
while (child) {
ListData data;
ListItem item;
attr = child->first_attribute("name");
if (!attr)
continue;
data.displayName = gui_parse_text(attr->value());
data.variableValue = gui_parse_text(child->value());
if (child->value() == currentValue) {
data.selected = 1;
} else {
data.selected = 0;
}
data.action = NULL;
item.displayName = gui_parse_text(attr->value());
item.variableValue = gui_parse_text(child->value());
item.selected = (child->value() == currentValue);
item.action = NULL;
xml_node<>* action = child->first_node("action");
if (action) {
data.action = new GUIAction(action);
item.action = new GUIAction(action);
allowSelection = true;
}
xml_node<>* variable_name = child->first_node("data");
if (variable_name) {
attr = variable_name->first_attribute("variable");
if (attr) {
data.variableName = attr->value();
if (DataManager::GetIntValue(data.variableName) == 0)
data.selected = 0;
else
data.selected = 1;
item.variableName = attr->value();
item.selected = (DataManager::GetIntValue(item.variableName) != 0);
allowSelection = true;
isCheckList = true;
}
}
mList.push_back(data);
LoadConditions(child, item.mConditions);
mListItems.push_back(item);
mVisibleItems.push_back(mListItems.size()-1);
child = child->next_sibling("listitem");
}
@@ -128,37 +124,46 @@ int GUIListBox::NotifyVarChange(const std::string& varName, const std::string& v
if(!isConditionTrue())
return 0;
if (isCheckList) {
int i, listSize = mList.size();
for (i = 0; i < listSize; i++) {
if (mList.at(i).variableName == varName) {
if (value == "0") {
mList.at(i).selected = 0;
} else {
mList.at(i).selected = 1;
}
}
}
mUpdate = 1;
return 0;
}
// Check to see if the variable that we are using to store the list selected value has been updated
if (varName == mVariable) {
int i, listSize = mList.size();
currentValue = value;
for (i = 0; i < listSize; i++) {
if (mList.at(i).variableValue == currentValue) {
mList.at(i).selected = 1;
SetVisibleListLocation(i);
} else
mList.at(i).selected = 0;
}
mUpdate = 1;
return 0;
}
std::vector<size_t> mVisibleItemsOld;
std::swap(mVisibleItemsOld, mVisibleItems);
for (size_t i = 0; i < mListItems.size(); i++) {
ListItem& item = mListItems[i];
// update per-item visibility condition
bool itemVisible = UpdateConditions(item.mConditions, varName);
if (itemVisible)
mVisibleItems.push_back(i);
if (isCheckList)
{
if (item.variableName == varName) {
item.selected = (value != "0");
mUpdate = 1;
}
}
else if (varName == mVariable) {
if (item.variableValue == currentValue) {
item.selected = 1;
SetVisibleListLocation(mVisibleItems.empty() ? 0 : mVisibleItems.size()-1);
} else {
item.selected = 0;
}
}
}
if (mVisibleItemsOld != mVisibleItems) {
mUpdate = 1; // some item's visibility has changed
if (firstDisplayedItem >= mVisibleItems.size()) {
// all items in the view area were removed - make last item visible
SetVisibleListLocation(mVisibleItems.empty() ? 0 : mVisibleItems.size()-1);
}
}
return 0;
}
@@ -173,15 +178,16 @@ void GUIListBox::SetPageFocus(int inFocus)
size_t GUIListBox::GetItemCount()
{
return mList.size();
return mVisibleItems.size();
}
void GUIListBox::RenderItem(size_t itemindex, int yPos, bool selected)
{
// note: the "selected" parameter above is for the currently touched item
// don't confuse it with the more persistent "selected" flag per list item used below
ImageResource* icon = mList.at(itemindex).selected ? mIconSelected : mIconUnselected;
const std::string& text = mList.at(itemindex).displayName;
ListItem& item = mListItems[mVisibleItems[itemindex]];
ImageResource* icon = item.selected ? mIconSelected : mIconUnselected;
const std::string& text = item.displayName;
RenderStdItem(yPos, selected, icon, text.c_str());
}
@@ -189,27 +195,24 @@ void GUIListBox::RenderItem(size_t itemindex, int yPos, bool selected)
void GUIListBox::NotifySelect(size_t item_selected)
{
if (!isCheckList) {
for (size_t i = 0; i < mList.size(); i++) {
mList.at(i).selected = 0;
// deselect all items, even invisible ones
for (size_t i = 0; i < mListItems.size(); i++) {
mListItems[i].selected = 0;
}
}
if (item_selected < mList.size()) {
ListData& data = mList.at(item_selected);
if (isCheckList) {
if (data.selected) {
data.selected = 0;
DataManager::SetValue(data.variableName, "0");
} else {
data.selected = 1;
DataManager::SetValue(data.variableName, "1");
}
} else {
data.selected = 1;
string str = data.variableValue; // [check] should this set currentValue instead?
DataManager::SetValue(mVariable, str);
}
if (data.action)
data.action->doActions();
ListItem& item = mListItems[mVisibleItems[item_selected]];
if (isCheckList) {
int selected = 1 - item.selected;
item.selected = selected;
DataManager::SetValue(item.variableName, selected ? "1" : "0");
} else {
item.selected = 1;
string str = item.variableValue; // [check] should this set currentValue instead?
DataManager::SetValue(mVariable, str);
}
if (item.action)
item.action->doActions();
mUpdate = 1;
}
+4 -2
View File
@@ -632,16 +632,18 @@ public:
virtual void NotifySelect(size_t item_selected);
protected:
struct ListData {
struct ListItem {
std::string displayName;
std::string variableName;
std::string variableValue;
unsigned int selected;
GUIAction* action;
std::vector<Condition> mConditions;
};
protected:
std::vector<ListData> mList;
std::vector<ListItem> mListItems;
std::vector<size_t> mVisibleItems; // contains indexes in mListItems of visible items only
std::string mVariable;
std::string currentValue;
ImageResource* mIconSelected;