summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gui/listbox.cpp131
-rw-r--r--gui/objects.hpp6
2 files changed, 71 insertions, 66 deletions
diff --git a/gui/listbox.cpp b/gui/listbox.cpp
index d82736e39..be2b48698 100644
--- a/gui/listbox.cpp
+++ b/gui/listbox.cpp
@@ -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;
+ mUpdate = 1;
+ }
- 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;
+ 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;
+ }
}
- mUpdate = 1;
- return 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;
}
diff --git a/gui/objects.hpp b/gui/objects.hpp
index 99bf0dbfa..7028956ad 100644
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -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;