* Improved Category filtering.

You can now easily hide games on category basis.
Click on a category to cycle through possible checkbox states.

The "ALL" category can now have 3 different states:
  [ ] Not checked = Doesn't display all categories (like before)
  [v] Checked     = Displays all categories (like before)
  [X] Cross       = Displays all categories except forbidden categories.

The other categories now have 4 different states:
  [ ] Not checked = Games containing this category are not filtered (like before)
  [v] Enabled     = All games containing this category will be displayed (like before)
  [X] Forbidden   = All games containing this category will NOT be displayed.
  [+] Required    = All games NOT containing this category will NOT be displayed.
This commit is contained in:
Cyan 2012-06-09 12:20:14 +00:00
parent 74eca1d38b
commit 5a52016f92
12 changed files with 395 additions and 22 deletions

View File

@ -2,8 +2,8 @@
<app version="1"> <app version="1">
<name> USB Loader GX</name> <name> USB Loader GX</name>
<coder>USB Loader GX Team</coder> <coder>USB Loader GX Team</coder>
<version>3.0 r1188</version> <version>3.0 r1189</version>
<release_date>201205191249</release_date> <release_date>201206090828</release_date>
<!-- // remove this line to enable arguments <!-- // remove this line to enable arguments
<arguments> <arguments>
<arg>--ios=250</arg> <arg>--ios=250</arg>

View File

@ -26,15 +26,17 @@
#define WHITEBOX_RED_SIZE 4 #define WHITEBOX_RED_SIZE 4
GuiCheckbox::GuiCheckbox(int s) GuiCheckbox::GuiCheckbox(int s)
: GuiButton(30, 30), Checked(false) : GuiButton(30, 30), Checked(false), MultiStates(false)
{ {
style = s; style = s;
Checksign.SetParent(this); Checksign.SetParent(this);
Cross.SetParent(this); Cross.SetParent(this);
Plus.SetParent(this);
Blackbox.SetParent(this); Blackbox.SetParent(this);
Whitebox.SetParent(this); Whitebox.SetParent(this);
Checksign.SetColor((GXColor) {0, 0, 0, 255}); Checksign.SetColor((GXColor) {0, 0, 0, 255});
Cross.SetColor((GXColor) {0, 0, 0, 255}); Cross.SetColor((GXColor) {0, 0, 0, 255});
Plus.SetColor((GXColor) {0, 0, 0, 255});
Blackbox.SetColor((GXColor) {0, 0, 0, 255}); Blackbox.SetColor((GXColor) {0, 0, 0, 255});
Whitebox.SetColor((GXColor) {255, 255, 255, 255}); Whitebox.SetColor((GXColor) {255, 255, 255, 255});
@ -42,15 +44,17 @@ GuiCheckbox::GuiCheckbox(int s)
} }
GuiCheckbox::GuiCheckbox(int w, int h, int s) GuiCheckbox::GuiCheckbox(int w, int h, int s)
: GuiButton(w, h), Checked(false) : GuiButton(w, h), Checked(false), MultiStates(false)
{ {
style = s; style = s;
Checksign.SetParent(this); Checksign.SetParent(this);
Cross.SetParent(this); Cross.SetParent(this);
Plus.SetParent(this);
Blackbox.SetParent(this); Blackbox.SetParent(this);
Whitebox.SetParent(this); Whitebox.SetParent(this);
Checksign.SetColor((GXColor) {0, 0, 0, 255}); Checksign.SetColor((GXColor) {0, 0, 0, 255});
Cross.SetColor((GXColor) {0, 0, 0, 255}); Cross.SetColor((GXColor) {0, 0, 0, 255});
Plus.SetColor((GXColor) {0, 0, 0, 255});
Blackbox.SetColor((GXColor) {0, 0, 0, 255}); Blackbox.SetColor((GXColor) {0, 0, 0, 255});
Whitebox.SetColor((GXColor) {255, 255, 255, 255}); Whitebox.SetColor((GXColor) {255, 255, 255, 255});
@ -65,6 +69,8 @@ void GuiCheckbox::SetSize(int w, int h)
Checksign.SetPosition(WHITEBOX_RED_SIZE/2, WHITEBOX_RED_SIZE/2); Checksign.SetPosition(WHITEBOX_RED_SIZE/2, WHITEBOX_RED_SIZE/2);
Cross.SetSize(w-WHITEBOX_RED_SIZE, h-WHITEBOX_RED_SIZE); Cross.SetSize(w-WHITEBOX_RED_SIZE, h-WHITEBOX_RED_SIZE);
Cross.SetPosition(WHITEBOX_RED_SIZE/2, WHITEBOX_RED_SIZE/2); Cross.SetPosition(WHITEBOX_RED_SIZE/2, WHITEBOX_RED_SIZE/2);
Plus.SetSize(w-WHITEBOX_RED_SIZE, h-WHITEBOX_RED_SIZE);
Plus.SetPosition(WHITEBOX_RED_SIZE/2, WHITEBOX_RED_SIZE/2);
Blackbox.SetSize(w, h); Blackbox.SetSize(w, h);
Whitebox.SetSize(w-WHITEBOX_RED_SIZE, h-WHITEBOX_RED_SIZE); Whitebox.SetSize(w-WHITEBOX_RED_SIZE, h-WHITEBOX_RED_SIZE);
Whitebox.SetPosition(WHITEBOX_RED_SIZE/2, WHITEBOX_RED_SIZE/2); Whitebox.SetPosition(WHITEBOX_RED_SIZE/2, WHITEBOX_RED_SIZE/2);
@ -86,7 +92,23 @@ void GuiCheckbox::SetTransparent(bool b)
void GuiCheckbox::SetState(int s, int c) void GuiCheckbox::SetState(int s, int c)
{ {
if(s == STATE_CLICKED) if(s == STATE_CLICKED)
Checked = !Checked; {
if(MultiStates)
{
if(!Checked)
Checked = !Checked;
else
style++;
if(style == MAX_CHECKBOX_STYLE)
{
Checked = !Checked;
style = CHECKSIGN;
}
}
else
Checked = !Checked;
}
GuiButton::SetState(s, c); GuiButton::SetState(s, c);
} }
@ -96,6 +118,7 @@ void GuiCheckbox::SetAlignment(int h, int v)
GuiButton::SetAlignment(h, v); GuiButton::SetAlignment(h, v);
Checksign.SetAlignment(h, v); Checksign.SetAlignment(h, v);
Cross.SetAlignment(h, v); Cross.SetAlignment(h, v);
Plus.SetAlignment(h, v);
Blackbox.SetAlignment(h, v); Blackbox.SetAlignment(h, v);
Whitebox.SetAlignment(h, v); Whitebox.SetAlignment(h, v);
@ -103,24 +126,28 @@ void GuiCheckbox::SetAlignment(int h, int v)
{ {
Checksign.SetPosition(-WHITEBOX_RED_SIZE/2, Checksign.GetTopPos()); Checksign.SetPosition(-WHITEBOX_RED_SIZE/2, Checksign.GetTopPos());
Cross.SetPosition(-WHITEBOX_RED_SIZE/2, Cross.GetTopPos()); Cross.SetPosition(-WHITEBOX_RED_SIZE/2, Cross.GetTopPos());
Plus.SetPosition(-WHITEBOX_RED_SIZE/2, Plus.GetTopPos());
Whitebox.SetPosition(-WHITEBOX_RED_SIZE/2, Whitebox.GetTopPos()); Whitebox.SetPosition(-WHITEBOX_RED_SIZE/2, Whitebox.GetTopPos());
} }
else if(h == ALIGN_CENTER) else if(h == ALIGN_CENTER)
{ {
Checksign.SetPosition(0, Checksign.GetTopPos()); Checksign.SetPosition(0, Checksign.GetTopPos());
Cross.SetPosition(0, Cross.GetTopPos()); Cross.SetPosition(0, Cross.GetTopPos());
Plus.SetPosition(0, Plus.GetTopPos());
Whitebox.SetPosition(0, Whitebox.GetTopPos()); Whitebox.SetPosition(0, Whitebox.GetTopPos());
} }
if(v == ALIGN_BOTTOM) if(v == ALIGN_BOTTOM)
{ {
Checksign.SetPosition(Checksign.GetLeftPos(), -WHITEBOX_RED_SIZE/2); Checksign.SetPosition(Checksign.GetLeftPos(), -WHITEBOX_RED_SIZE/2);
Cross.SetPosition(Cross.GetLeftPos(), -WHITEBOX_RED_SIZE/2); Cross.SetPosition(Cross.GetLeftPos(), -WHITEBOX_RED_SIZE/2);
Plus.SetPosition(Plus.GetLeftPos(), -WHITEBOX_RED_SIZE/2);
Whitebox.SetPosition(Whitebox.GetLeftPos(), -WHITEBOX_RED_SIZE/2); Whitebox.SetPosition(Whitebox.GetLeftPos(), -WHITEBOX_RED_SIZE/2);
} }
else if(v == ALIGN_MIDDLE) else if(v == ALIGN_MIDDLE)
{ {
Checksign.SetPosition(Checksign.GetLeftPos(), 0); Checksign.SetPosition(Checksign.GetLeftPos(), 0);
Cross.SetPosition(Cross.GetLeftPos(), 0); Cross.SetPosition(Cross.GetLeftPos(), 0);
Plus.SetPosition(Plus.GetLeftPos(), 0);
Whitebox.SetPosition(Whitebox.GetLeftPos(), 0); Whitebox.SetPosition(Whitebox.GetLeftPos(), 0);
} }
} }
@ -134,6 +161,8 @@ void GuiCheckbox::Draw()
{ {
if(style == CHECKSIGN) if(style == CHECKSIGN)
Checksign.Draw(); Checksign.Draw();
else if (style == PLUS)
Plus.Draw();
else else
Cross.Draw(); Cross.Draw();
} }

View File

@ -28,6 +28,7 @@
#include "GUI/gui_box.hpp" #include "GUI/gui_box.hpp"
#include "GUI/gui_cross.hpp" #include "GUI/gui_cross.hpp"
#include "GUI/gui_checksign.hpp" #include "GUI/gui_checksign.hpp"
#include "GUI/gui_plus.hpp"
class GuiCheckbox : public GuiButton class GuiCheckbox : public GuiButton
{ {
@ -39,21 +40,28 @@ class GuiCheckbox : public GuiButton
void SetClickSize(int w, int h); void SetClickSize(int w, int h);
void SetAlignment(int h, int v); void SetAlignment(int h, int v);
void SetChecked(bool c) { LOCK(this); Checked = c; } void SetChecked(bool c) { LOCK(this); Checked = c; }
void SetStyle(int st) { LOCK(this); style = st; }
void SetMultiStates(bool m) { LOCK(this); MultiStates = m; }
bool IsChecked() const { return Checked; } bool IsChecked() const { return Checked; }
int GetStyle() { return style; }
virtual void SetState(int s, int c = -1); virtual void SetState(int s, int c = -1);
virtual void Draw(); virtual void Draw();
enum enum
{ {
CHECKSIGN, CHECKSIGN,
CROSS, CROSS,
PLUS,
MAX_CHECKBOX_STYLE
}; };
protected: protected:
GuiChecksign Checksign; GuiChecksign Checksign;
GuiCross Cross; GuiCross Cross;
GuiPlus Plus;
GuiBox Blackbox; GuiBox Blackbox;
GuiBox Whitebox; GuiBox Whitebox;
int style; int style;
bool Checked; bool Checked;
bool MultiStates;
}; };

View File

@ -110,6 +110,37 @@ bool GuiCheckboxBrowser::AddEntrie(const string &text, bool checked)
return true; return true;
} }
bool GuiCheckboxBrowser::AddEntrieMultiStates(const string &text, bool checked, int style)
{
LOCK(this);
int currentSize = checkBoxList.size();
textLineList.resize(currentSize+1);
checkBoxList.resize(currentSize+1);
checkBoxList[currentSize] = new GuiCheckbox(30, 30);
checkBoxList[currentSize]->SetParent(this);
checkBoxList[currentSize]->SetChecked(checked);
checkBoxList[currentSize]->SetStyle(style);
checkBoxList[currentSize]->SetMultiStates(true);
checkBoxList[currentSize]->SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
checkBoxList[currentSize]->SetTrigger(&trigA);
checkBoxList[currentSize]->SetClickSize(width-30-scrollBar.GetWidth(), 30);
checkBoxList[currentSize]->Clicked.connect(this, &GuiCheckboxBrowser::OnCheckboxClick);
textLineList[currentSize] = new GuiText(text.c_str(), 18, thColor("r=0 g=0 b=0 a=255 - checkbox browser text color"));
textLineList[currentSize]->SetParent(this);
textLineList[currentSize]->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
textLineList[currentSize]->SetMaxWidth(maxTextWidth, DOTTED);
if(textLineDrawn.size() < (u32) maxSize)
{
textLineDrawn.push_back(textLineList[currentSize]);
checkBoxDrawn.push_back(checkBoxList[currentSize]);
}
return true;
}
void GuiCheckboxBrowser::OnCheckboxClick(GuiButton *sender, int chan, const POINT &pointer) void GuiCheckboxBrowser::OnCheckboxClick(GuiButton *sender, int chan, const POINT &pointer)
{ {
LOCK(this); LOCK(this);

View File

@ -37,6 +37,7 @@ class GuiCheckboxBrowser : public GuiElement, public sigslot::has_slots<>
GuiCheckboxBrowser(int w, int h, int maxSize = 7); GuiCheckboxBrowser(int w, int h, int maxSize = 7);
virtual ~GuiCheckboxBrowser(); virtual ~GuiCheckboxBrowser();
bool AddEntrie(const string &text, bool checked = false); bool AddEntrie(const string &text, bool checked = false);
bool AddEntrieMultiStates(const string &text, bool checked = false, int style = CHECKSIGN);
int GetSelected() const { return pageIndex+selectedItem; } int GetSelected() const { return pageIndex+selectedItem; }
bool IsChecked(u32 i) { if(i >= checkBoxList.size()) return false; else return checkBoxList[i]->IsChecked(); } bool IsChecked(u32 i) { if(i >= checkBoxList.size()) return false; else return checkBoxList[i]->IsChecked(); }
GuiCheckbox *GetCheckbox(u32 i) { if(i >= checkBoxList.size()) return NULL; else return checkBoxList[i]; } GuiCheckbox *GetCheckbox(u32 i) { if(i >= checkBoxList.size()) return NULL; else return checkBoxList[i]; }
@ -47,6 +48,13 @@ class GuiCheckboxBrowser : public GuiElement, public sigslot::has_slots<>
void Draw(); void Draw();
void Update(GuiTrigger *t); void Update(GuiTrigger *t);
sigslot::signal2<GuiCheckbox *, int> checkBoxClicked; sigslot::signal2<GuiCheckbox *, int> checkBoxClicked;
enum
{
CHECKSIGN,
CROSS,
PLUS,
MAX_CHECKBOX_STYLE
};
private: private:
void onListChange(int SelItem, int SelInd); void onListChange(int SelItem, int SelInd);
void OnCheckboxClick(GuiButton *sender, int chan, const POINT &pointer); void OnCheckboxClick(GuiButton *sender, int chan, const POINT &pointer);

53
source/GUI/gui_plus.cpp Normal file
View File

@ -0,0 +1,53 @@
/****************************************************************************
* Copyright (C) 2012
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include "gui_plus.hpp"
void GuiPlus::Draw()
{
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
f32 x1 = GetLeft() + width*0.15f;
f32 x2 = GetLeft() + width*0.5f;
f32 x3 = GetLeft() + width - width*0.15f;
f32 y1 = GetTop() + height*0.15f;
f32 y2 = GetTop() + height*0.5f;
f32 y3 = GetTop() + height - height*0.15f;
int alpha = GetAlpha();
GX_Begin(GX_LINES, GX_VTXFMT0, 4);
GX_Position3f32(x2, y1, 0.0f);
GX_Color4u8(color.r, color.g, color.b, alpha);
GX_Position3f32(x2, y3, 0.0f);
GX_Color4u8(color.r, color.g, color.b, alpha);
GX_Position3f32(x1, y2, 0.0f);
GX_Color4u8(color.r, color.g, color.b, alpha);
GX_Position3f32(x3, y2, 0.0f);
GX_Color4u8(color.r, color.g, color.b, alpha);
GX_End();
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
}

43
source/GUI/gui_plus.hpp Normal file
View File

@ -0,0 +1,43 @@
/****************************************************************************
* Copyright (C) 2012
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef GUIPLUS_HPP_
#define GUIPLUS_HPP_
#include "GUI/gui.h"
class GuiPlus : public GuiElement
{
public:
GuiPlus() : Linewidth(2.0f) { color = (GXColor) {0, 0, 0, 255}; GX_SetLineWidth((u8) (Linewidth*6.0f), 0); }
//! Max line width is 42.5 pixel
void SetLinewidth(float w) { LOCK(this); Linewidth = w; GX_SetLineWidth((u8) (Linewidth*6.0f), 0); }
void SetColor(const GXColor c) { LOCK(this); color = c; }
void SetSize(int w, int h) { LOCK(this); width = w; height = h; }
void Draw();
protected:
GXColor color;
float Linewidth;
};
#endif

View File

@ -27,7 +27,8 @@
#include "language/gettext.h" #include "language/gettext.h"
CategorySwitchPrompt::CategorySwitchPrompt() CategorySwitchPrompt::CategorySwitchPrompt()
: CategoryPrompt(tr("Show Categories")), oldSetting(Settings.EnabledCategories) : CategoryPrompt(tr("Show Categories")), oldSettingEnabled(Settings.EnabledCategories),
oldSettingRequired(Settings.RequiredCategories), oldSettingForbidden(Settings.ForbiddenCategories)
{ {
browser->checkBoxClicked.connect(this, &CategorySwitchPrompt::OnCheckboxClick); browser->checkBoxClicked.connect(this, &CategorySwitchPrompt::OnCheckboxClick);
browserRefresh.connect(this, &CategorySwitchPrompt::onBrowserRefresh); browserRefresh.connect(this, &CategorySwitchPrompt::onBrowserRefresh);
@ -38,7 +39,9 @@ CategorySwitchPrompt::CategorySwitchPrompt()
void CategorySwitchPrompt::onResetChanges() void CategorySwitchPrompt::onResetChanges()
{ {
Settings.EnabledCategories = oldSetting; Settings.EnabledCategories = oldSettingEnabled;
Settings.RequiredCategories = oldSettingRequired;
Settings.ForbiddenCategories = oldSettingForbidden;
GameCategories.Load(Settings.ConfigPath); GameCategories.Load(Settings.ConfigPath);
} }
@ -49,7 +52,9 @@ void CategorySwitchPrompt::onBrowserRefresh()
do do
{ {
bool checked = false; bool checked = false;
int style = CHECKSIGN;
// Verify the Enabled Categories [v]
for(u32 i = 0; i < Settings.EnabledCategories.size(); ++i) for(u32 i = 0; i < Settings.EnabledCategories.size(); ++i)
{ {
if(Settings.EnabledCategories[i] == GameCategories.CategoryList.getCurrentID()) if(Settings.EnabledCategories[i] == GameCategories.CategoryList.getCurrentID())
@ -58,8 +63,32 @@ void CategorySwitchPrompt::onBrowserRefresh()
break; break;
} }
} }
browser->AddEntrie(tr(GameCategories.CategoryList.getCurrentName().c_str()), checked); // Verify the Forbidden Categories [X]
if(!checked)
for(u32 i = 0; i < Settings.ForbiddenCategories.size(); ++i)
{
if(Settings.ForbiddenCategories[i] == GameCategories.CategoryList.getCurrentID())
{
checked = true;
style = CROSS;
break;
}
}
// Verify the Required Categories [+]
if(!checked)
for(u32 i = 0; i < Settings.RequiredCategories.size(); ++i)
{
if(Settings.RequiredCategories[i] == GameCategories.CategoryList.getCurrentID())
{
checked = true;
style = PLUS;
break;
}
}
browser->AddEntrieMultiStates(tr(GameCategories.CategoryList.getCurrentName().c_str()), checked, style);
} }
while(GameCategories.CategoryList.goToNext()); while(GameCategories.CategoryList.goToNext());
@ -74,22 +103,69 @@ void CategorySwitchPrompt::OnCheckboxClick(GuiCheckbox *checkBox, int index)
GameCategories.CategoryList.goToNext(); GameCategories.CategoryList.goToNext();
u32 i; u32 i;
for(i = 0; i < Settings.EnabledCategories.size(); ++i) if(!checkBox->IsChecked())
{ {
if(Settings.EnabledCategories[i] == GameCategories.CategoryList.getCurrentID()) // Remove from Required
for(i = 0; i < Settings.RequiredCategories.size(); ++i)
{ {
if(!checkBox->IsChecked()) if(Settings.RequiredCategories[i] == GameCategories.CategoryList.getCurrentID())
{ {
Settings.EnabledCategories.erase(Settings.EnabledCategories.begin()+i); Settings.RequiredCategories.erase(Settings.RequiredCategories.begin()+i);
markChanged(); markChanged();
break;
} }
break;
} }
} }
else if(checkBox->GetStyle() == CHECKSIGN)
if(i == Settings.EnabledCategories.size() && checkBox->IsChecked())
{ {
// Add to Enabled
Settings.EnabledCategories.push_back(GameCategories.CategoryList.getCurrentID()); Settings.EnabledCategories.push_back(GameCategories.CategoryList.getCurrentID());
markChanged(); markChanged();
} }
else if(checkBox->GetStyle() == CROSS)
{
// Remove from Enabled
for(i = 0; i < Settings.EnabledCategories.size(); ++i)
{
if(Settings.EnabledCategories[i] == GameCategories.CategoryList.getCurrentID())
{
Settings.EnabledCategories.erase(Settings.EnabledCategories.begin()+i);
break;
}
}
// Add to Forbidden
Settings.ForbiddenCategories.push_back(GameCategories.CategoryList.getCurrentID());
markChanged();
}
else if(checkBox->GetStyle() == PLUS && index > 0)
{
// Remove from Forbidden
for(i = 0; i < Settings.ForbiddenCategories.size(); ++i)
{
if(Settings.ForbiddenCategories[i] == GameCategories.CategoryList.getCurrentID())
{
Settings.ForbiddenCategories.erase(Settings.ForbiddenCategories.begin()+i);
break;
}
}
// Add to Required
Settings.RequiredCategories.push_back(GameCategories.CategoryList.getCurrentID());
markChanged();
}
// Override Style cycling for category "All"
if(index == 0 && checkBox->GetStyle() == PLUS)
{
checkBox->SetStyle(CHECKSIGN);
checkBox->SetChecked(false);
for(i = 0; i < Settings.ForbiddenCategories.size(); ++i)
{
if(Settings.ForbiddenCategories[i] == GameCategories.CategoryList.getCurrentID())
{
Settings.ForbiddenCategories.erase(Settings.ForbiddenCategories.begin()+i);
markChanged();
break;
}
}
}
} }

View File

@ -35,7 +35,16 @@ class CategorySwitchPrompt : public CategoryPrompt
void onBrowserRefresh(); void onBrowserRefresh();
void onResetChanges(); void onResetChanges();
const std::vector<u32> oldSetting; const std::vector<u32> oldSettingEnabled;
const std::vector<u32> oldSettingRequired;
const std::vector<u32> oldSettingForbidden;
}; };
enum
{
CHECKSIGN,
CROSS,
PLUS,
MAX_CHECKBOX_STYLE
};
#endif #endif

View File

@ -133,6 +133,8 @@ void CSettings::SetDefault()
ClockFontScaleFactor = 1.0f; // Scale of 1 to prevent misaligned clock. ClockFontScaleFactor = 1.0f; // Scale of 1 to prevent misaligned clock.
EnabledCategories.resize(1); EnabledCategories.resize(1);
EnabledCategories[0] = 0; EnabledCategories[0] = 0;
RequiredCategories.resize(0);
ForbiddenCategories.resize(0);
Wiinnertag = OFF; Wiinnertag = OFF;
SelectedGame = 0; SelectedGame = 0;
GameListOffset = 0; GameListOffset = 0;
@ -333,6 +335,22 @@ bool CSettings::Save()
fprintf(file, ","); fprintf(file, ",");
} }
fprintf(file, "\n"); fprintf(file, "\n");
fprintf(file, "RequiredCategories = ");
for(u32 i = 0; i < RequiredCategories.size(); ++i)
{
fprintf(file, "%i", RequiredCategories[i]);
if(i+1 < RequiredCategories.size())
fprintf(file, ",");
}
fprintf(file, "\n");
fprintf(file, "ForbiddenCategories = ");
for(u32 i = 0; i < ForbiddenCategories.size(); ++i)
{
fprintf(file, "%i", ForbiddenCategories[i]);
if(i+1 < ForbiddenCategories.size())
fprintf(file, ",");
}
fprintf(file, "\n");
fprintf(file, "Wiinnertag = %d\n", Wiinnertag); fprintf(file, "Wiinnertag = %d\n", Wiinnertag);
fprintf(file, "WiinnertagPath = %s\n", WiinnertagPath); fprintf(file, "WiinnertagPath = %s\n", WiinnertagPath);
fprintf(file, "SelectedGame = %d\n", SelectedGame); fprintf(file, "SelectedGame = %d\n", SelectedGame);
@ -940,6 +958,44 @@ bool CSettings::SetSetting(char *name, char *value)
} }
return true; return true;
} }
else if (strcmp(name, "RequiredCategories") == 0)
{
RequiredCategories.clear();
char * strTok = strtok(value, ",");
while (strTok != NULL)
{
u32 id = atoi(strTok);
u32 i;
for(i = 0; i < RequiredCategories.size(); ++i)
{
if(RequiredCategories[i] == id)
break;
}
if(i == RequiredCategories.size())
RequiredCategories.push_back(id);
strTok = strtok(NULL,",");
}
return true;
}
else if (strcmp(name, "ForbiddenCategories") == 0)
{
ForbiddenCategories.clear();
char * strTok = strtok(value, ",");
while (strTok != NULL)
{
u32 id = atoi(strTok);
u32 i;
for(i = 0; i < ForbiddenCategories.size(); ++i)
{
if(ForbiddenCategories[i] == id)
break;
}
if(i == ForbiddenCategories.size())
ForbiddenCategories.push_back(id);
strTok = strtok(NULL,",");
}
return true;
}
return false; return false;
} }

View File

@ -137,6 +137,8 @@ class CSettings
short GameListOffset; short GameListOffset;
short sneekVideoPatch; short sneekVideoPatch;
std::vector<u32> EnabledCategories; std::vector<u32> EnabledCategories;
std::vector<u32> RequiredCategories;
std::vector<u32> ForbiddenCategories;
u8 EntryIOS; u8 EntryIOS;
short NandEmuMode; short NandEmuMode;
short NandEmuChanMode; short NandEmuChanMode;

View File

@ -229,14 +229,72 @@ void GameList::InternalFilterList(std::vector<struct discHdr> &FullList)
//! Category filter //! Category filter
u32 n; u32 n;
for(n = 0; n < Settings.EnabledCategories.size(); ++n) enum { DISABLED, ENABLED, HIDEFORBIDDEN };
int allType = DISABLED;
// verify the display mode for category "All"
for(u32 n = 0; n < Settings.EnabledCategories.size(); ++n)
{ {
if(GameCategories.isInCategory((char *) header->id, Settings.EnabledCategories[n])) if(Settings.EnabledCategories[n] == 0)
{
allType = ENABLED; // All = Enabled
break; break;
}
} }
if(n == Settings.EnabledCategories.size()) for(u32 n = 0; n < Settings.ForbiddenCategories.size(); ++n)
continue; {
if(Settings.ForbiddenCategories[n] == 0)
{
allType = HIDEFORBIDDEN; // All = Enabled but hide Forbidden categories
break;
}
}
if(allType == DISABLED)
{
// Remove TitleID if it contains a forbidden categories
for(n = 0; n < Settings.ForbiddenCategories.size(); ++n)
{
if(GameCategories.isInCategory((char *) header->id, Settings.ForbiddenCategories[n]))
break;
}
if(n < Settings.ForbiddenCategories.size())
continue;
// Remove TitleID is it doesn't contain a required categories
for(n = 0; n < Settings.RequiredCategories.size(); ++n)
{
if(!GameCategories.isInCategory((char *) header->id, Settings.RequiredCategories[n]))
break;
}
if(n < Settings.RequiredCategories.size())
continue;
// If there's no required categories, verify if the TitleID should be kept or removed
if(Settings.RequiredCategories.size() == 0)
{
for(n = 0; n < Settings.EnabledCategories.size(); ++n)
{
if(GameCategories.isInCategory((char *) header->id, Settings.EnabledCategories[n]))
break;
}
if(n == Settings.EnabledCategories.size())
continue;
}
}
if(allType == HIDEFORBIDDEN)
{
// Remove TitleID if it contains a forbidden categories
for(n = 0; n < Settings.ForbiddenCategories.size(); ++n)
{
if(GameCategories.isInCategory((char *) header->id, Settings.ForbiddenCategories[n]))
if(Settings.ForbiddenCategories[n] >0)
break;
}
if(n < Settings.ForbiddenCategories.size())
continue;
}
FilteredList.push_back(header); FilteredList.push_back(header);
} }
} }