summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-08-04 19:55:59 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-08-04 19:55:59 (GMT)
commit5a2da01a5b1d59bae3d1f00132230835e6803301 (patch)
treea580fe32daa8bac4acb002d32f51552a00c30e72 /src
parent82d2bcc7c2fe7ae5ba40b915ce22422a36d68639 (diff)
downloadpowder-5a2da01a5b1d59bae3d1f00132230835e6803301.zip
powder-5a2da01a5b1d59bae3d1f00132230835e6803301.tar.gz
Tags, fixes #55
Diffstat (limited to 'src')
-rw-r--r--src/client/Client.cpp49
-rw-r--r--src/client/Client.h1
-rw-r--r--src/interface/Appearance.cpp9
-rw-r--r--src/interface/Appearance.h2
-rw-r--r--src/interface/Button.cpp39
-rw-r--r--src/search/SearchController.cpp14
-rw-r--r--src/search/SearchController.h2
-rw-r--r--src/search/SearchModel.cpp58
-rw-r--r--src/search/SearchModel.h4
-rw-r--r--src/search/SearchView.cpp99
-rw-r--r--src/search/SearchView.h3
11 files changed, 252 insertions, 28 deletions
diff --git a/src/client/Client.cpp b/src/client/Client.cpp
index 2684689..5d1e439 100644
--- a/src/client/Client.cpp
+++ b/src/client/Client.cpp
@@ -1262,6 +1262,55 @@ std::vector<SaveComment*> * Client::GetComments(int saveID, int start, int count
return commentArray;
}
+std::vector<std::pair<std::string, int> > * Client::GetTags(int start, int count, string query, int & resultCount)
+{
+ lastError = "";
+ resultCount = 0;
+ std::vector<std::pair<std::string, int> > * tagArray = new std::vector<std::pair<std::string, int> >();
+ std::stringstream urlStream;
+ char * data;
+ int dataStatus, dataLength;
+ urlStream << "http://" << SERVER << "/Browse/Tags.json?Start=" << start << "&Count=" << count;
+ if(query.length())
+ {
+ urlStream << "&Search_Query=";
+ if(query.length())
+ urlStream << URLEscape(query);
+ }
+
+ data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
+ if(dataStatus == 200 && data)
+ {
+ try
+ {
+ std::istringstream dataStream(data);
+ json::Object objDocument;
+ json::Reader::Read(objDocument, dataStream);
+
+ json::Number tempCount = objDocument["TagTotal"];
+ resultCount = tempCount.Value();
+ json::Array tagsArray = objDocument["Tags"];
+ for(int j = 0; j < tagsArray.Size(); j++)
+ {
+ json::Number tagCount = tagsArray[j]["Count"];
+ json::String tag = tagsArray[j]["Tag"];
+ tagArray->push_back(std::pair<std::string, int>(tag.Value(), tagCount.Value()));
+ }
+ }
+ catch (json::Exception &e)
+ {
+ lastError = "Could not read response";
+ }
+ }
+ else
+ {
+ lastError = http_ret_text(dataStatus);
+ }
+ if(data)
+ free(data);
+ return tagArray;
+}
+
std::vector<SaveInfo*> * Client::SearchSaves(int start, int count, string query, string sort, std::string category, int & resultCount)
{
lastError = "";
diff --git a/src/client/Client.h b/src/client/Client.h
index 453342a..bea6ffc 100644
--- a/src/client/Client.h
+++ b/src/client/Client.h
@@ -111,6 +111,7 @@ public:
LoginStatus Login(string username, string password, User & user);
void ClearThumbnailRequests();
std::vector<SaveInfo*> * SearchSaves(int start, int count, string query, string sort, string category, int & resultCount);
+ std::vector<std::pair<std::string, int> > * GetTags(int start, int count, string query, int & resultCount);
std::vector<SaveComment*> * GetComments(int saveID, int start, int count);
Thumbnail * GetPreview(int saveID, int saveDate);
Thumbnail * GetThumbnail(int saveID, int saveDate);
diff --git a/src/interface/Appearance.cpp b/src/interface/Appearance.cpp
index b504d02..45c3592 100644
--- a/src/interface/Appearance.cpp
+++ b/src/interface/Appearance.cpp
@@ -14,18 +14,21 @@ namespace ui
HorizontalAlign(AlignCentre),
VerticalAlign(AlignMiddle),
- BackgroundHover(30, 30, 30),
+ BackgroundHover(20, 20, 20),
BackgroundInactive(0, 0, 0),
BackgroundActive(255, 255, 255),
- BackgroundDisabled(100, 100, 100),
+ BackgroundDisabled(10, 10, 10),
TextHover(255, 255, 255),
TextInactive(255, 255, 255),
TextActive(0, 0, 0),
+ TextDisabled(100, 100, 100),
BorderHover(255, 255, 255),
BorderInactive(200, 200, 200),
- BorderActive(255, 255, 255),
+ BorderActive(235, 235, 235),
+ BorderDisabled(100, 100, 100),
+
Margin(1, 4),
icon(NoIcon),
diff --git a/src/interface/Appearance.h b/src/interface/Appearance.h
index 4767edb..e6f0a93 100644
--- a/src/interface/Appearance.h
+++ b/src/interface/Appearance.h
@@ -40,10 +40,12 @@ namespace ui
ui::Colour TextHover;
ui::Colour TextInactive;
ui::Colour TextActive;
+ ui::Colour TextDisabled;
ui::Colour BorderHover;
ui::Colour BorderInactive;
ui::Colour BorderActive;
+ ui::Colour BorderDisabled;
ui::Border Margin;
diff --git a/src/interface/Button.cpp b/src/interface/Button.cpp
index 996c02f..a9b0606 100644
--- a/src/interface/Button.cpp
+++ b/src/interface/Button.cpp
@@ -86,32 +86,45 @@ void Button::Draw(const Point& screenPos)
Graphics * g = ui::Engine::Ref().g;
Point Position = screenPos;
ui::Colour bgColour(0, 0, 0);
+
+ ui::Colour textColour = Appearance.TextInactive;
+ ui::Colour borderColour = Appearance.BorderInactive;
+ ui::Colour backgroundColour = Appearance.BackgroundInactive;
+
if(Enabled)
{
if(isButtonDown || (isTogglable && toggle))
{
- bgColour = Appearance.BackgroundActive;
- g->fillrect(Position.X+1, Position.Y+1, Size.X-2, Size.Y-2, Appearance.BackgroundActive.Red, Appearance.BackgroundActive.Green, Appearance.BackgroundActive.Blue, 255);
- g->drawrect(Position.X, Position.Y, Size.X, Size.Y, Appearance.BorderActive.Red, Appearance.BorderActive.Green, Appearance.BorderActive.Blue, 255);
- g->drawtext(Position.X+textPosition.X, Position.Y+textPosition.Y, buttonDisplayText, Appearance.TextActive.Red, Appearance.TextActive.Green, Appearance.TextActive.Blue, 255);
+ textColour = Appearance.TextActive;
+ borderColour = Appearance.BorderActive;
+ backgroundColour = Appearance.BackgroundActive;
+ }
+ else if (isMouseInside)
+ {
+ textColour = Appearance.TextHover;
+ borderColour = Appearance.BorderHover;
+ backgroundColour = Appearance.BackgroundHover;
}
else
{
- bgColour = Appearance.BackgroundInactive;
- g->fillrect(Position.X+1, Position.Y+1, Size.X-2, Size.Y-2, Appearance.BackgroundInactive.Red, Appearance.BackgroundInactive.Green, Appearance.BackgroundInactive.Blue, 255);
- g->drawrect(Position.X, Position.Y, Size.X, Size.Y, Appearance.BorderInactive.Red, Appearance.BorderInactive.Green, Appearance.BorderInactive.Blue, 255);
- g->drawtext(Position.X+textPosition.X, Position.Y+textPosition.Y, buttonDisplayText, Appearance.TextInactive.Red, Appearance.TextInactive.Green, Appearance.TextInactive.Blue, 255);
+ textColour = Appearance.TextInactive;
+ borderColour = Appearance.BorderInactive;
+ backgroundColour = Appearance.BackgroundInactive;
}
}
else
{
- bgColour = Appearance.BackgroundInactive;
- g->fillrect(Position.X+1, Position.Y+1, Size.X-2, Size.Y-2, Appearance.BackgroundInactive.Red, Appearance.BackgroundInactive.Green, Appearance.BackgroundInactive.Blue, 180);
- g->drawrect(Position.X, Position.Y, Size.X, Size.Y, Appearance.BackgroundDisabled.Red, Appearance.BackgroundDisabled.Green, Appearance.BackgroundDisabled.Blue, Appearance.BackgroundDisabled.Alpha);
- g->drawtext(Position.X+textPosition.X, Position.Y+textPosition.Y, buttonDisplayText, 180, 180, 180, 255);
+ textColour = Appearance.TextDisabled;
+ borderColour = Appearance.BorderDisabled;
+ backgroundColour = Appearance.BackgroundDisabled;
}
- bool iconInvert = (bgColour.Blue + (3*bgColour.Green) + (2*bgColour.Red))>544?true:false;
+ bgColour = Appearance.BackgroundInactive;
+ g->fillrect(Position.X+1, Position.Y+1, Size.X-2, Size.Y-2, backgroundColour.Red, backgroundColour.Green, backgroundColour.Blue, backgroundColour.Alpha);
+ g->drawrect(Position.X, Position.Y, Size.X, Size.Y, borderColour.Red, borderColour.Green, borderColour.Blue, borderColour.Alpha);
+ g->drawtext(Position.X+textPosition.X, Position.Y+textPosition.Y, buttonDisplayText, textColour.Red, textColour.Green, textColour.Blue, textColour.Alpha);
+
+ bool iconInvert = (backgroundColour.Blue + (3*backgroundColour.Green) + (2*backgroundColour.Red))>544?true:false;
if(Appearance.icon)
{
diff --git a/src/search/SearchController.cpp b/src/search/SearchController.cpp
index f127354..cd1e5f0 100644
--- a/src/search/SearchController.cpp
+++ b/src/search/SearchController.cpp
@@ -96,11 +96,19 @@ SearchController::~SearchController()
delete searchView;
}
-void SearchController::DoSearch(std::string query)
+void SearchController::DoSearch(std::string query, bool now)
{
nextQuery = query;
- nextQueryTime = clock()+(0.6 * CLOCKS_PER_SEC);
- nextQueryDone = false;
+ if(!now)
+ {
+ nextQueryTime = clock()+(0.6 * CLOCKS_PER_SEC);
+ nextQueryDone = false;
+ }
+ else
+ {
+ nextQueryDone = true;
+ searchModel->UpdateSaveList(1, nextQuery);
+ }
//searchModel->UpdateSaveList(1, query);
}
diff --git a/src/search/SearchController.h b/src/search/SearchController.h
index 16b4039..32ca8b3 100644
--- a/src/search/SearchController.h
+++ b/src/search/SearchController.h
@@ -30,7 +30,7 @@ public:
~SearchController();
SearchView * GetView() { return searchView; }
void Exit();
- void DoSearch(std::string query);
+ void DoSearch(std::string query, bool now = false);
void NextPage();
void PrevPage();
void ChangeSort();
diff --git a/src/search/SearchModel.cpp b/src/search/SearchModel.cpp
index 9449673..63231d7 100644
--- a/src/search/SearchModel.cpp
+++ b/src/search/SearchModel.cpp
@@ -12,10 +12,16 @@ SearchModel::SearchModel():
updateSaveListFinished(false),
saveListLoaded(false),
currentPage(1),
- resultCount(0)
+ resultCount(0),
+ showTags(true)
{
}
+void SearchModel::SetShowTags(bool show)
+{
+ showTags = show;
+}
+
void * SearchModel::updateSaveListTHelper(void * obj)
{
return ((SearchModel *)obj)->updateSaveListT();
@@ -23,14 +29,27 @@ void * SearchModel::updateSaveListTHelper(void * obj)
void * SearchModel::updateSaveListT()
{
+ void ** information = new void*[2];
+
std::string category = "";
if(showFavourite)
category = "Favourites";
if(showOwn && Client::Ref().GetAuthUser().ID)
category = "by:"+Client::Ref().GetAuthUser().Username;
- vector<SaveInfo*> * tempSaveList = Client::Ref().SearchSaves((currentPage-1)*20, 20, lastQuery, currentSort=="new"?"date":"votes", category, resultCount);
+ information[0] = Client::Ref().SearchSaves((currentPage-1)*20, 20, lastQuery, currentSort=="new"?"date":"votes", category, resultCount);
+
+ if(showTags)
+ {
+ int tagResultCount;
+ information[1] = Client::Ref().GetTags(0, 24, "", tagResultCount);
+ }
+ else
+ {
+ information[1] = NULL;
+ }
+
updateSaveListFinished = true;
- return tempSaveList;
+ return information;
}
void SearchModel::UpdateSaveList(int pageNumber, std::string query)
@@ -46,6 +65,11 @@ void SearchModel::UpdateSaveList(int pageNumber, std::string query)
selected.clear();
notifySelectedChanged();
+ if(pageNumber == 1 && !showOwn && !showFavourite && currentSort == "best" && query == "")
+ SetShowTags(true);
+ else
+ SetShowTags(false);
+
//Threading
if(!updateSaveListWorking)
{
@@ -78,6 +102,11 @@ vector<SaveInfo*> SearchModel::GetSaveList()
return saveList;
}
+vector<pair<string, int> > SearchModel::GetTagList()
+{
+ return tagList;
+}
+
void SearchModel::Update()
{
if(updateSaveListWorking)
@@ -87,10 +116,25 @@ void SearchModel::Update()
updateSaveListWorking = false;
lastError = "";
saveListLoaded = true;
- vector<SaveInfo*> * tempSaveList;
- pthread_join(updateSaveListThread, (void**)(&tempSaveList));
- saveList = *tempSaveList;
- delete tempSaveList;
+ void ** tempInformation;
+ //vector<SaveInfo*> * tempSaveList;
+ pthread_join(updateSaveListThread, (void**)(&tempInformation));
+ saveList = *(vector<SaveInfo*>*)tempInformation[0];
+
+ delete (vector<SaveInfo*>*)tempInformation[0];
+
+ if(tempInformation[1])
+ {
+ tagList = *(vector<pair<string, int> >*)tempInformation[1];
+ delete (vector<pair<string, int> >*)tempInformation[1];
+ }
+ else
+ {
+ tagList = vector<pair<string, int> >();
+ }
+
+ delete[] tempInformation;
+
if(!saveList.size())
{
lastError = Client::Ref().GetLastError();
diff --git a/src/search/SearchModel.h b/src/search/SearchModel.h
index 831e141..385ff05 100644
--- a/src/search/SearchModel.h
+++ b/src/search/SearchModel.h
@@ -21,10 +21,12 @@ private:
vector<int> selected;
vector<SearchView*> observers;
vector<SaveInfo*> saveList;
+ vector<pair<string, int> > tagList;
int currentPage;
int resultCount;
bool showOwn;
bool showFavourite;
+ bool showTags;
void notifySaveListChanged();
void notifySelectedChanged();
void notifyPageChanged();
@@ -43,9 +45,11 @@ public:
SearchModel();
virtual ~SearchModel();
+ void SetShowTags(bool show);
void AddObserver(SearchView * observer);
void UpdateSaveList(int pageNumber, std::string query);
vector<SaveInfo*> GetSaveList();
+ vector<pair<string, int> > GetTagList();
string GetLastError() { return lastError; }
int GetPageCount() { return max(1, (int)(ceil(resultCount/16))); }
int GetPageNum() { return currentPage; }
diff --git a/src/search/SearchView.cpp b/src/search/SearchView.cpp
index 16d03ed..cf02985 100644
--- a/src/search/SearchView.cpp
+++ b/src/search/SearchView.cpp
@@ -16,6 +16,7 @@ SearchView::SearchView():
nextButton = new ui::Button(ui::Point(XRES+BARSIZE-52, YRES+MENUSIZE-18), ui::Point(50, 16), "Next \x95");
previousButton = new ui::Button(ui::Point(1, YRES+MENUSIZE-18), ui::Point(50, 16), "\x96 Prev");
infoLabel = new ui::Label(ui::Point(51, YRES+MENUSIZE-18), ui::Point(XRES+BARSIZE-102, 16), "Loading...");
+ tagsLabel = new ui::Label(ui::Point(51, YRES+MENUSIZE-18), ui::Point(XRES+BARSIZE-102, 16), "Popular Tags:");
class SearchAction : public ui::TextboxAction
{
@@ -219,6 +220,12 @@ SearchView::~SearchView()
delete infoLabel;
}
+void SearchView::Search(std::string query)
+{
+ searchField->SetText(query);
+ c->DoSearch(query, true);
+}
+
void SearchView::NotifySortChanged(SearchModel * sender)
{
sortButton->SetText("Show "+sender->GetSort());
@@ -293,14 +300,29 @@ void SearchView::NotifySaveListChanged(SearchModel * sender)
int buttonWidth, buttonHeight, saveX = 0, saveY = 0, savesX = 5, savesY = 4, buttonPadding = 1;
int buttonAreaWidth, buttonAreaHeight, buttonXOffset, buttonYOffset;
+ int tagWidth, tagHeight, tagX = 0, tagY = 0, tagsX = 6, tagsY = 4, tagPadding = 1;
+ int tagAreaWidth, tagAreaHeight, tagXOffset, tagYOffset;
+
vector<SaveInfo*> saves = sender->GetSaveList();
+ vector<pair<string, int> > tags = sender->GetTagList();
+ //string messageOfTheDay = sender->GetMessageOfTheDay();
+
+ RemoveComponent(tagsLabel);
+ tagsLabel->SetParentWindow(NULL);
+
Client::Ref().ClearThumbnailRequests();
for(i = 0; i < saveButtons.size(); i++)
{
RemoveComponent(saveButtons[i]);
delete saveButtons[i];
}
+ for(i = 0; i < tagButtons.size(); i++)
+ {
+ RemoveComponent(tagButtons[i]);
+ delete tagButtons[i];
+ }
saveButtons.clear();
+ tagButtons.clear();
if(!sender->GetSavesLoaded())
{
nextButton->Enabled = false;
@@ -341,12 +363,34 @@ void SearchView::NotifySaveListChanged(SearchModel * sender)
delete errorLabel;
errorLabel = NULL;
}
- buttonXOffset = buttonPadding;
+
buttonYOffset = 28;
+ buttonXOffset = buttonPadding;
buttonAreaWidth = Size.X;
buttonAreaHeight = Size.Y - buttonYOffset - 18;
+
+ if(tags.size())
+ {
+ buttonYOffset += (buttonAreaHeight/savesY) - buttonPadding*2;
+ buttonAreaHeight = Size.Y - buttonYOffset - 18;
+ savesY--;
+
+ tagXOffset = tagPadding;
+ tagYOffset = 60;
+ tagAreaWidth = Size.X;
+ tagAreaHeight = ((buttonAreaHeight/savesY) - buttonPadding*2)-(tagYOffset-28)-5;
+ tagWidth = (tagAreaWidth/tagsX) - tagPadding*2;
+ tagHeight = (tagAreaHeight/tagsY) - tagPadding*2;
+
+ AddComponent(tagsLabel);
+ tagsLabel->Position.Y = tagYOffset-16;
+ }
+
buttonWidth = (buttonAreaWidth/savesX) - buttonPadding*2;
buttonHeight = (buttonAreaHeight/savesY) - buttonPadding*2;
+
+
+
class SaveOpenAction: public ui::SaveButtonAction
{
SearchView * v;
@@ -361,6 +405,59 @@ void SearchView::NotifySaveListChanged(SearchModel * sender)
v->c->Selected(sender->GetSave()->GetID(), sender->GetSelected());
}
};
+
+ class TagAction: public ui::ButtonAction
+ {
+ SearchView * v;
+ std::string tag;
+ public:
+ TagAction(SearchView * v, std::string tag) : v(v), tag(tag) {}
+ virtual void ActionCallback(ui::Button * sender)
+ {
+ v->Search(tag);
+ }
+ };
+
+ for(i = 0; i < tags.size(); i++)
+ {
+ int maxTagVotes = tags[0].second;
+
+ pair<string, int> tag = tags[i];
+
+ if(tagX == tagsX)
+ {
+ if(tagY == tagsY-1)
+ break;
+ tagX = 0;
+ tagY++;
+ }
+
+ int tagAlpha = 192;
+ if (maxTagVotes)
+ tagAlpha = 127+(128*tag.second)/maxTagVotes;
+
+ ui::Button * tagButton;
+ tagButton = new ui::Button(
+ ui::Point(
+ tagXOffset + tagPadding + tagX*(tagWidth+tagPadding*2),
+ tagYOffset + tagPadding + tagY*(tagHeight+tagPadding*2)
+ ),
+ ui::Point(tagWidth, tagHeight),
+ tag.first
+ );
+ tagButton->SetActionCallback(new TagAction(this, tag.first));
+ tagButton->Appearance.BorderInactive = ui::Colour(0, 0, 0);
+ tagButton->Appearance.BorderHover = ui::Colour(0, 0, 0);
+ tagButton->Appearance.BorderActive = ui::Colour(0, 0, 0);
+ tagButton->Appearance.BackgroundHover = ui::Colour(0, 0, 0);
+
+ tagButton->Appearance.TextInactive = ui::Colour(tagAlpha, tagAlpha, tagAlpha);
+ tagButton->Appearance.TextHover = ui::Colour((tagAlpha*5)/6, (tagAlpha*5)/6, tagAlpha);
+ AddComponent(tagButton);
+ tagButtons.push_back(tagButton);
+ tagX++;
+
+ }
for(i = 0; i < saves.size(); i++)
{
if(saveX == savesX)
diff --git a/src/search/SearchView.h b/src/search/SearchView.h
index 6e27f06..abded85 100644
--- a/src/search/SearchView.h
+++ b/src/search/SearchView.h
@@ -19,12 +19,14 @@ class SearchView: public ui::Window
private:
SearchController * c;
vector<ui::SaveButton*> saveButtons;
+ vector<ui::Button*> tagButtons;
ui::Button * favButton;
ui::Button * nextButton;
ui::Button * previousButton;
ui::Label * errorLabel;
ui::Textbox * searchField;
ui::Label * infoLabel;
+ ui::Label * tagsLabel;
ui::Button * sortButton;
ui::Button * ownButton;
ui::Spinner * loadingSpinner;
@@ -44,6 +46,7 @@ public:
SearchView();
virtual ~SearchView();
void AttachController(SearchController * _c) { c = _c; }
+ virtual void Search(std::string);
virtual void OnTick(float dt);
virtual void OnMouseWheel(int x, int y, int d);
virtual void OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt);