Apply patch by xenux to filter addons, thanks a lot\!
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@13035 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
1a5a3be3cc
commit
27642f332c
@ -5,11 +5,22 @@
|
||||
<div x="0" y="0" width="100%" layout="horizontal-row" height="8%">
|
||||
<icon-button id="back" height="100%" icon="gui/back.png"/>
|
||||
<header text_align="center" proportion="1" text="SuperTuxKart Addons" align="center"/>
|
||||
<button id="reload" I18N="Reload button to reload addon data" text="Reload" />
|
||||
<spacer width="15" height="10" />
|
||||
<button id="reload" I18N="Reload button to reload addon data" text="Reload" />
|
||||
</div>
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
<box id="filter_box" width="97%" height="75" layout="vertical-row" align="center">
|
||||
<div x="0" y="0" width="98%" height="100%" layout="horizontal-row" align="center">
|
||||
<textbox id="filter_name" proportion="9" align="center" />
|
||||
<spacer width="10" />
|
||||
<label text="Updated" align="center" />
|
||||
<spinner id="filter_date" proportion="5" align="center" min_value="0" wrap_around="true"/>
|
||||
<label text="Rating >=" align="center"/>
|
||||
<spinner id="filter_rating" proportion="3" align="center" min_value="0" wrap_around="true"/>
|
||||
<icon-button id="filter_search" height="100%" icon="gui/search.png"/>
|
||||
</div>
|
||||
</box>
|
||||
|
||||
<spacer height="25" width="10"/>
|
||||
|
||||
<tabs id="category" height="10%" max_height="110" width="90%" align="center">
|
||||
<icon-button id="tab_kart" width="128" height="128" icon="gui/karts.png"
|
||||
|
BIN
data/gui/search.png
Normal file
BIN
data/gui/search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
@ -177,3 +177,42 @@ bool Addon::testIncluded(const std::string &min_ver, const std::string &max_ver)
|
||||
|
||||
return (min_version <= current_version && max_version >= current_version);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Filter the add-on with a list of words.
|
||||
* \param words A list of words separated by ' '.
|
||||
* \return true if the add-on contains one of the words, otherwise false.
|
||||
*/
|
||||
bool Addon::filterByWords(const core::stringw words) const
|
||||
{
|
||||
if (words == NULL || words.empty())
|
||||
return true;
|
||||
|
||||
std::vector<core::stringw> list = StringUtils::split(words, ' ', false);
|
||||
|
||||
for (unsigned int i = 0; i < list.size(); i++)
|
||||
{
|
||||
list[i].make_lower();
|
||||
|
||||
core::stringw name = core::stringw(m_name).make_lower();
|
||||
if (name.find(list[i].c_str()) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
core::stringw designer = core::stringw(m_designer).make_lower();
|
||||
if (designer.find(list[i].c_str()) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
core::stringw description = core::stringw(m_description).make_lower();
|
||||
if (description.find(list[i].c_str()) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} // filterByWords
|
||||
|
@ -266,6 +266,9 @@ public:
|
||||
return file_manager->getAddonsFile(getTypeDirectory()+m_dir_name);
|
||||
} // getDataDir
|
||||
// ------------------------------------------------------------------------
|
||||
bool filterByWords(const core::stringw words) const;
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** Compares two addons according to the sort order currently defined.
|
||||
* \param a The addon to compare this addon to.
|
||||
*/
|
||||
|
@ -40,6 +40,18 @@ DEFINE_SCREEN_SINGLETON( AddonsScreen );
|
||||
AddonsScreen::AddonsScreen() : Screen("addons_screen.stkgui")
|
||||
{
|
||||
m_selected_index = -1;
|
||||
|
||||
// Add date filters.
|
||||
m_date_filters.push_back((DateFilter) {_("All") , 0, 0, 0});
|
||||
m_date_filters.push_back((DateFilter) {_("1 week") , 0, 0, 7});
|
||||
m_date_filters.push_back((DateFilter) {_("2 weeks") , 0, 0, 12});
|
||||
m_date_filters.push_back((DateFilter) {_("1 month") , 0, 1, 0});
|
||||
m_date_filters.push_back((DateFilter) {_("3 months") , 0, 3, 0});
|
||||
m_date_filters.push_back((DateFilter) {_("6 months") , 0, 6, 0});
|
||||
m_date_filters.push_back((DateFilter) {_("9 months") , 0, 9, 0});
|
||||
m_date_filters.push_back((DateFilter) {_("1 year") , 1, 0, 0});
|
||||
m_date_filters.push_back((DateFilter) {_("2 years") , 2, 0, 0});
|
||||
|
||||
} // AddonsScreen
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -70,6 +82,7 @@ void AddonsScreen::loadedFromFile()
|
||||
GUIEngine::ListWidget* w_list =
|
||||
getWidget<GUIEngine::ListWidget>("list_addons");
|
||||
w_list->setColumnListener(this);
|
||||
|
||||
} // loadedFromFile
|
||||
|
||||
|
||||
@ -83,8 +96,32 @@ void AddonsScreen::beforeAddingWidget()
|
||||
w_list->clearColumns();
|
||||
w_list->addColumn( _("Add-on name"), 2 );
|
||||
w_list->addColumn( _("Updated date"), 1 );
|
||||
}
|
||||
|
||||
GUIEngine::SpinnerWidget* w_filter_date =
|
||||
getWidget<GUIEngine::SpinnerWidget>("filter_date");
|
||||
w_filter_date->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
|
||||
w_filter_date->m_properties[GUIEngine::PROP_MAX_VALUE] =
|
||||
StringUtils::toString(m_date_filters.size() - 1);
|
||||
|
||||
for (int n = 0; n < m_date_filters.size(); n++)
|
||||
{
|
||||
w_filter_date->addLabel(m_date_filters[n].label);
|
||||
}
|
||||
|
||||
w_filter_date->setValue(0);
|
||||
|
||||
GUIEngine::SpinnerWidget* w_filter_rating =
|
||||
getWidget<GUIEngine::SpinnerWidget>("filter_rating");
|
||||
w_filter_rating->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
|
||||
w_filter_rating->m_properties[GUIEngine::PROP_MAX_VALUE] = "4";
|
||||
|
||||
for (int n = 0; n < 5; n++)
|
||||
{
|
||||
w_filter_rating->addLabel(StringUtils::toWString(1.0 + n / 2.0));
|
||||
}
|
||||
|
||||
w_filter_rating->setValue(0);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void AddonsScreen::init()
|
||||
@ -147,6 +184,27 @@ void AddonsScreen::tearDown()
|
||||
*/
|
||||
void AddonsScreen::loadList()
|
||||
{
|
||||
|
||||
// Get the filter by words.
|
||||
GUIEngine::TextBoxWidget* w_filter_name =
|
||||
getWidget<GUIEngine::TextBoxWidget>("filter_name");
|
||||
core::stringw words = w_filter_name->getText();
|
||||
|
||||
// Get the filter by date.
|
||||
GUIEngine::SpinnerWidget* w_filter_date =
|
||||
getWidget<GUIEngine::SpinnerWidget>("filter_date");
|
||||
int date_index = w_filter_date->getValue();
|
||||
Time::TimeType date = Time::getTimeSinceEpoch();
|
||||
date = Time::addInterval(date,
|
||||
-m_date_filters[date_index].year,
|
||||
-m_date_filters[date_index].month,
|
||||
-m_date_filters[date_index].day);
|
||||
|
||||
// Get the filter by rating.
|
||||
GUIEngine::SpinnerWidget* w_filter_rating =
|
||||
getWidget<GUIEngine::SpinnerWidget>("filter_rating");
|
||||
float rating = 1.0 + w_filter_rating->getValue() / 2.0;
|
||||
|
||||
// First create a list of sorted entries
|
||||
PtrVector<const Addon, REF> sorted_list;
|
||||
for(unsigned int i=0; i<addons_manager->getNumAddons(); i++)
|
||||
@ -163,6 +221,19 @@ void AddonsScreen::loadList()
|
||||
if (!addon.isInstalled() && (addons_manager->wasError()
|
||||
|| UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED ))
|
||||
continue;
|
||||
|
||||
// Filter by rating.
|
||||
if (addon.getRating() < rating)
|
||||
continue;
|
||||
|
||||
// Filter by date.
|
||||
if (date_index != 0 && Time::compareTime(date, addon.getDate()) > 0)
|
||||
continue;
|
||||
|
||||
// Filter by name, designer and description.
|
||||
if (!addon.filterByWords(words))
|
||||
continue;
|
||||
|
||||
sorted_list.push_back(&addon);
|
||||
}
|
||||
sorted_list.insertionSort(/*start=*/0, m_sort_desc);
|
||||
@ -364,6 +435,11 @@ void AddonsScreen::eventCallback(GUIEngine::Widget* widget,
|
||||
loadList();
|
||||
}
|
||||
}
|
||||
else if (name == "filter_search")
|
||||
{
|
||||
loadList();
|
||||
}
|
||||
|
||||
} // eventCallback
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -28,6 +28,13 @@ namespace irr { namespace gui { class STKModifiedSpriteBank; } }
|
||||
|
||||
namespace GUIEngine { class Widget; }
|
||||
|
||||
struct DateFilter {
|
||||
core::stringw label;
|
||||
int year;
|
||||
int month;
|
||||
int day;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Addons screen
|
||||
* \ingroup states_screens
|
||||
@ -70,6 +77,9 @@ private:
|
||||
/** \brief To check (and set) if sort order is descending **/
|
||||
bool m_sort_desc;
|
||||
|
||||
/** List of date filters **/
|
||||
std::vector<DateFilter> m_date_filters;
|
||||
|
||||
public:
|
||||
|
||||
/** Load the addons into the main list.*/
|
||||
|
@ -86,6 +86,35 @@ public:
|
||||
{
|
||||
return irr_driver->getDevice()->getTimer()->getRealTime()/1000.0;
|
||||
}; // getTimeSinceEpoch
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Compare two different times.
|
||||
* \return A signed integral indicating the relation between the time.
|
||||
*/
|
||||
static int compareTime(TimeType time1, TimeType time2)
|
||||
{
|
||||
double diff = difftime(time1, time2);
|
||||
|
||||
if (diff > 0)
|
||||
return 1;
|
||||
else if (diff < 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}; // compareTime
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Add a interval to a time.
|
||||
*/
|
||||
static TimeType addInterval(TimeType time, int year, int month, int day) {
|
||||
struct tm t = *gmtime(&time);
|
||||
t.tm_year += year;
|
||||
t.tm_mon += month;
|
||||
t.tm_mday += day;
|
||||
return mktime(&t);
|
||||
}
|
||||
|
||||
class ScopeProfiler
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user