diff --git a/src/PowderToy.cpp b/src/PowderToy.cpp index f8be79387..a13a817ff 100644 --- a/src/PowderToy.cpp +++ b/src/PowderToy.cpp @@ -92,10 +92,22 @@ int main(int argc, char * argv[]) engine->onMouseMove(event.motion.x, event.motion.y); break; case SDL_MOUSEBUTTONDOWN: - engine->onMouseClick(event.motion.x, event.motion.y, event.button.button); + if(event.button.button == SDL_BUTTON_WHEELUP) + { + engine->onMouseWheel(event.motion.x, event.motion.y, 1); + } + else if (event.button.button == SDL_BUTTON_WHEELDOWN) + { + engine->onMouseWheel(event.motion.x, event.motion.y, -1); + } + else + { + engine->onMouseClick(event.motion.x, event.motion.y, event.button.button); + } break; case SDL_MOUSEBUTTONUP: - engine->onMouseUnclick(event.motion.x, event.motion.y, event.button.button); + if(event.button.button != SDL_BUTTON_WHEELUP && event.button.button != SDL_BUTTON_WHEELDOWN) + engine->onMouseUnclick(event.motion.x, event.motion.y, event.button.button); break; } event.type = 0; //Clear last event diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 1d450c7c0..ff6fb974c 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -39,9 +39,10 @@ Client::~Client() http_done(); } -std::vector * Client::SearchSaves(int start, int count, string query, string sort) +std::vector * Client::SearchSaves(int start, int count, string query, string sort, int & resultCount) { lastError = ""; + resultCount = 0; std::vector * saveArray = new std::vector(); std::stringstream urlStream; char * data; @@ -52,7 +53,7 @@ std::vector * Client::SearchSaves(int start, int count, string query, str urlStream << "&Search_Query="; if(query.length()) urlStream << query; - if(sort.length()) + if(sort == "date") { if(query.length()) urlStream << " "; @@ -69,6 +70,8 @@ std::vector * Client::SearchSaves(int start, int count, string query, str json::Object objDocument; json::Reader::Read(objDocument, dataStream); + json::Number tempCount = objDocument["Count"]; + resultCount = tempCount.Value(); json::Array savesArray = objDocument["Saves"]; for(int j = 0; j < savesArray.Size(); j++) { @@ -132,7 +135,7 @@ Thumbnail * Client::GetThumbnail(int saveID, int saveDate) { activeThumbRequestCompleteTimes[i] = time(NULL); } - else if(activeThumbRequestCompleteTimes[i] < (currentTime-20)) //Otherwise, if it completed more than 10 seconds ago, destroy it. + else if(activeThumbRequestCompleteTimes[i] < (currentTime-2)) //Otherwise, if it completed more than 2 seconds ago, destroy it. { http_async_req_close(activeThumbRequests[i]); activeThumbRequests[i] = NULL; @@ -165,6 +168,7 @@ Thumbnail * Client::GetThumbnail(int saveID, int saveDate) char * data; int status, data_size, imgw, imgh; data = http_async_req_stop(activeThumbRequests[i], &status, &data_size); + free(activeThumbRequests[i]); activeThumbRequests[i] = NULL; if (status == 200 && data) { @@ -203,10 +207,6 @@ Thumbnail * Client::GetThumbnail(int saveID, int saveDate) return thumbnailCache[thumbnailCacheNextID++]; } } - else if(activeThumbRequestTimes[i] < currentTime-HTTP_TIMEOUT) - { - // - } } } if(!found) diff --git a/src/client/Client.h b/src/client/Client.h index 7f6ca2c7e..678b3e73e 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -24,7 +24,7 @@ public: Client(); ~Client(); void ClearThumbnailRequests(); - std::vector * SearchSaves(int start, int count, string query, string sort); + std::vector * SearchSaves(int start, int count, string query, string sort, int & resultCount); Thumbnail * GetThumbnail(int saveID, int saveDate); std::string GetLastError() { return lastError; } }; diff --git a/src/game/GameController.cpp b/src/game/GameController.cpp index d8cff8bf9..571833a9e 100644 --- a/src/game/GameController.cpp +++ b/src/game/GameController.cpp @@ -9,7 +9,8 @@ using namespace std; -GameController::GameController() +GameController::GameController(): + search(NULL) { gameView = new GameView(); gameModel = new GameModel(); @@ -22,6 +23,11 @@ GameController::GameController() GameController::~GameController() { + if(search) + { + ui::Engine::Ref().CloseWindow(); + delete search; + } delete gameView; delete gameModel; } @@ -70,6 +76,6 @@ void GameController::SetPaused(bool pauseState) void GameController::OpenSearch() { - SearchController * search = new SearchController(); + search = new SearchController(); ui::Engine::Ref().ShowWindow(search->GetView()); } diff --git a/src/game/GameController.h b/src/game/GameController.h index 63d8e5e5b..c2c578d3c 100644 --- a/src/game/GameController.h +++ b/src/game/GameController.h @@ -6,6 +6,7 @@ #include "GameModel.h" #include "interface/Point.h" #include "simulation/Simulation.h" +#include "search/SearchController.h" using namespace std; @@ -17,6 +18,7 @@ private: //Simulation * sim; GameView * gameView; GameModel * gameModel; + SearchController * search; public: GameController(); ~GameController(); diff --git a/src/interface/Button.h b/src/interface/Button.h index aabca91c5..41a057b75 100644 --- a/src/interface/Button.h +++ b/src/interface/Button.h @@ -19,6 +19,7 @@ class ButtonAction { public: virtual void ActionCallback(ui::Button * sender) {} + virtual ~ButtonAction() {} }; class Button : public Component diff --git a/src/interface/SaveButton.cpp b/src/interface/SaveButton.cpp index 658a96913..38fb974ff 100644 --- a/src/interface/SaveButton.cpp +++ b/src/interface/SaveButton.cpp @@ -61,8 +61,7 @@ void SaveButton::Tick(float dt) tempThumb = Client::Ref().GetThumbnail(save->GetID(), 0); if(tempThumb) { - thumbnail = tempThumb; //Store a local copy of the thumbnail - cout << (void *)(tempThumb) << " " << (void *)(&thumbnail) << endl; + thumbnail = new Thumbnail(*tempThumb); //Store a local copy of the thumbnail if(thumbnail->Data) { if(thumbnail->Size.Y > (Size.Y-25)) diff --git a/src/interface/SaveButton.h b/src/interface/SaveButton.h index 34652c102..8019a3c8e 100644 --- a/src/interface/SaveButton.h +++ b/src/interface/SaveButton.h @@ -15,6 +15,7 @@ class SaveButtonAction { public: virtual void ActionCallback(ui::SaveButton * sender) {} + virtual ~SaveButtonAction() {} }; class SaveButton : public Component diff --git a/src/interface/Textbox.cpp b/src/interface/Textbox.cpp index 3cedc156b..f087241f4 100644 --- a/src/interface/Textbox.cpp +++ b/src/interface/Textbox.cpp @@ -162,13 +162,14 @@ void Textbox::OnKeyPress(int key, bool shift, bool ctrl, bool alt) cursor++; changed = true; } + break; } if(changed && actionCallback) { actionCallback->TextChangedCallback(this); } } - catch(std::out_of_range e) + catch(std::out_of_range &e) { cursor = 0; text = ""; diff --git a/src/interface/Textbox.h b/src/interface/Textbox.h index 5cd14f4d2..099368f0e 100644 --- a/src/interface/Textbox.h +++ b/src/interface/Textbox.h @@ -13,6 +13,7 @@ class TextboxAction { public: virtual void TextChangedCallback(ui::Textbox * sender) {} + virtual ~TextboxAction() {} }; class Textbox : public Component { diff --git a/src/search/SearchController.cpp b/src/search/SearchController.cpp index a9b346faa..710359107 100644 --- a/src/search/SearchController.cpp +++ b/src/search/SearchController.cpp @@ -11,7 +11,7 @@ SearchController::SearchController() searchModel->AddObserver(searchView); searchView->AttachController(this); - searchModel->UpdateSaveList(""); + searchModel->UpdateSaveList(1, ""); //Set up interface //windowPanel.AddChild(); @@ -25,5 +25,34 @@ SearchController::~SearchController() void SearchController::DoSearch(std::string query) { - searchModel->UpdateSaveList(query); + searchModel->UpdateSaveList(1, query); +} + +void SearchController::PrevPage() +{ + if(searchModel->GetPageNum()>1) + searchModel->UpdateSaveList(searchModel->GetPageNum()-1, searchModel->GetLastQuery()); +} + +void SearchController::NextPage() +{ + if(searchModel->GetPageNum() <= searchModel->GetPageCount()) + searchModel->UpdateSaveList(searchModel->GetPageNum()+1, searchModel->GetLastQuery()); +} + +void SearchController::ChangeSort() +{ + if(searchModel->GetSort() == "date") + { + searchModel->SetSort("votes"); + } + else + { + searchModel->SetSort("date"); + } +} + +void SearchController::ShowOwn(bool show) +{ + } diff --git a/src/search/SearchController.h b/src/search/SearchController.h index cbef93ac2..c9fdb21ee 100644 --- a/src/search/SearchController.h +++ b/src/search/SearchController.h @@ -16,6 +16,10 @@ public: ~SearchController(); SearchView * GetView() { return searchView; } void DoSearch(std::string query); + void NextPage(); + void PrevPage(); + void ChangeSort(); + void ShowOwn(bool show); }; #endif // SEARCHCONTROLLER_H diff --git a/src/search/SearchModel.cpp b/src/search/SearchModel.cpp index 3b2d0e085..adb8cad1d 100644 --- a/src/search/SearchModel.cpp +++ b/src/search/SearchModel.cpp @@ -3,26 +3,30 @@ #include "client/Client.h" -SearchModel::SearchModel() +SearchModel::SearchModel(): + currentSort("votes"), + showOwn(false) { } -void SearchModel::UpdateSaveList(std::string query) +void SearchModel::UpdateSaveList(int pageNumber, std::string query) { + lastQuery = query; lastError = ""; saveList.clear(); + currentPage = 1; + resultCount = 0; notifySaveListChanged(); - vector * tempSaveList = Client::Ref().SearchSaves(0, 12, query, ""); + notifyPageChanged(); + vector * tempSaveList = Client::Ref().SearchSaves((pageNumber-1)*12, 12, query, currentSort, resultCount); saveList = *tempSaveList; delete tempSaveList; if(!saveList.size()) { lastError = Client::Ref().GetLastError(); } - /*for(int i = 0; i < 16; i++) - { - saveList.push_back(Save(2198, 2333, 315, "dima-gord", "Destroyable city 5 (wth metro)")); - }*/ + currentPage = pageNumber; + notifyPageChanged(); notifySaveListChanged(); } @@ -35,6 +39,9 @@ void SearchModel::AddObserver(SearchView * observer) { observers.push_back(observer); observer->NotifySaveListChanged(this); + observer->NotifyPageChanged(this); + observer->NotifySortChanged(this); + observer->NotifyShowOwnChanged(this); } void SearchModel::notifySaveListChanged() @@ -45,3 +52,30 @@ void SearchModel::notifySaveListChanged() cObserver->NotifySaveListChanged(this); } } + +void SearchModel::notifyPageChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + SearchView* cObserver = observers[i]; + cObserver->NotifyPageChanged(this); + } +} + +void SearchModel::notifySortChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + SearchView* cObserver = observers[i]; + cObserver->NotifySortChanged(this); + } +} + +void SearchModel::notifyShowOwnChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + SearchView* cObserver = observers[i]; + cObserver->NotifyShowOwnChanged(this); + } +} diff --git a/src/search/SearchModel.h b/src/search/SearchModel.h index a2d73cbcc..dbd675746 100644 --- a/src/search/SearchModel.h +++ b/src/search/SearchModel.h @@ -3,6 +3,7 @@ #include #include +#include #include "Save.h" #include "SearchView.h" @@ -12,16 +13,31 @@ class SearchView; class SearchModel { private: + string currentSort; + string lastQuery; string lastError; vector observers; vector saveList; + int currentPage; + int resultCount; + bool showOwn; void notifySaveListChanged(); + void notifyPageChanged(); + void notifySortChanged(); + void notifyShowOwnChanged(); public: SearchModel(); void AddObserver(SearchView * observer); - void UpdateSaveList(std::string query); + void UpdateSaveList(int pageNumber, std::string query); vector GetSaveList(); string GetLastError() { return lastError; } + int GetPageCount() { return max(1, (int)(ceil(resultCount/16))); } + int GetPageNum() { return currentPage; } + std::string GetLastQuery() { return lastQuery; } + void SetSort(string sort) { currentSort = sort; UpdateSaveList(currentPage, lastQuery); notifySortChanged(); } + string GetSort() { return currentSort; } + void SetShowOwn(bool show) { showOwn = show; UpdateSaveList(currentPage, lastQuery); notifyShowOwnChanged(); } + bool GetShowOwn() { return showOwn; } }; #endif // SEARCHMODEL_H diff --git a/src/search/SearchView.cpp b/src/search/SearchView.cpp index 53ab44388..ca848b5a8 100644 --- a/src/search/SearchView.cpp +++ b/src/search/SearchView.cpp @@ -1,4 +1,7 @@ +#include + #include "SearchView.h" +#include "client/Client.h" #include "interface/SaveButton.h" #include "interface/Label.h" #include "interface/Textbox.h" @@ -9,8 +12,10 @@ SearchView::SearchView(): saveButtons(vector()), errorLabel(NULL) { + 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..."); class SearchAction : public ui::TextboxAction { @@ -26,11 +31,65 @@ SearchView::SearchView(): searchField->SetAlignment(AlignLeft, AlignBottom); searchField->SetActionCallback(new SearchAction(this)); + class SortAction : public ui::ButtonAction + { + SearchView * v; + public: + SortAction(SearchView * _v) { v = _v; } + void ActionCallback(ui::Button * sender) + { + v->c->ChangeSort(); + } + }; + sortButton = new ui::Button(ui::Point(XRES+BARSIZE-50-50-16-10, 10), ui::Point(50, 16), "Sort"); + sortButton->SetActionCallback(new SortAction(this)); + sortButton->SetAlignment(AlignLeft, AlignBottom); + AddComponent(sortButton); + + class MyOwnAction : public ui::ButtonAction + { + SearchView * v; + public: + MyOwnAction(SearchView * _v) { v = _v; } + void ActionCallback(ui::Button * sender) + { + v->c->ShowOwn(sender->GetToggleState()); + } + }; + ownButton = new ui::Button(ui::Point(XRES+BARSIZE-50-16-10, 10), ui::Point(50, 16), "My Own"); + ownButton->SetTogglable(true); + ownButton->SetActionCallback(new MyOwnAction(this)); + ownButton->SetAlignment(AlignLeft, AlignBottom); + AddComponent(ownButton); + + class NextPageAction : public ui::ButtonAction + { + SearchView * v; + public: + NextPageAction(SearchView * _v) { v = _v; } + void ActionCallback(ui::Button * sender) + { + v->c->NextPage(); + } + }; + nextButton->SetActionCallback(new NextPageAction(this)); nextButton->SetAlignment(AlignRight, AlignBottom); + class PrevPageAction : public ui::ButtonAction + { + SearchView * v; + public: + PrevPageAction(SearchView * _v) { v = _v; } + void ActionCallback(ui::Button * sender) + { + v->c->PrevPage(); + } + }; + previousButton->SetActionCallback(new PrevPageAction(this)); previousButton->SetAlignment(AlignLeft, AlignBottom); AddComponent(nextButton); AddComponent(previousButton); AddComponent(searchField); + AddComponent(infoLabel); ui::Label * searchPrompt = new ui::Label(ui::Point(10, 10), ui::Point(50, 16), "Search:"); searchPrompt->SetAlignment(AlignLeft, AlignBottom); @@ -46,6 +105,39 @@ SearchView::~SearchView() { } +void SearchView::NotifySortChanged(SearchModel * sender) +{ + sortButton->SetText("Sort: "+sender->GetSort()); +} + +void SearchView::NotifyShowOwnChanged(SearchModel * sender) +{ + sortButton->SetToggleState(sender->GetShowOwn()); +} + +void SearchView::NotifyPageChanged(SearchModel * sender) +{ + std::stringstream pageInfo; + pageInfo << "Page " << sender->GetPageNum() << " of " << sender->GetPageCount(); + infoLabel->SetText(pageInfo.str()); + if(sender->GetPageNum() == 1) + { + previousButton->Visible = false; + } + else + { + previousButton->Visible = true; + } + if(sender->GetPageNum() == sender->GetPageCount()) + { + nextButton->Visible = false; + } + else + { + nextButton->Visible = true; + } +} + void SearchView::NotifySaveListChanged(SearchModel * sender) { int i = 0; @@ -53,6 +145,13 @@ void SearchView::NotifySaveListChanged(SearchModel * sender) int buttonAreaWidth, buttonAreaHeight, buttonXOffset, buttonYOffset; vector saves = sender->GetSaveList(); + Client::Ref().ClearThumbnailRequests(); + for(i = 0; i < saveButtons.size(); i++) + { + RemoveComponent(saveButtons[i]); + delete saveButtons[i]; + } + saveButtons.clear(); if(!saves.size()) { if(!errorLabel) @@ -61,9 +160,9 @@ void SearchView::NotifySaveListChanged(SearchModel * sender) AddComponent(errorLabel); } if(sender->GetLastError().length()) - errorLabel->SetText(sender->GetLastError()); + errorLabel->SetText("\bo" + sender->GetLastError()); else - errorLabel->SetText("No saves found"); + errorLabel->SetText("\boNo saves found"); } else { @@ -79,13 +178,6 @@ void SearchView::NotifySaveListChanged(SearchModel * sender) buttonAreaHeight = Size.Y - buttonYOffset - 18; buttonWidth = (buttonAreaWidth/savesX) - buttonPadding*2; buttonHeight = (buttonAreaHeight/savesY) - buttonPadding*2; - for(i = 0; i < saveButtons.size(); i++) - { - RemoveComponent(saveButtons[i]); - - delete saveButtons[i]; - } - saveButtons.clear(); for(i = 0; i < saves.size(); i++) { if(saveX == savesX) diff --git a/src/search/SearchView.h b/src/search/SearchView.h index 8777c3039..370877eb8 100644 --- a/src/search/SearchView.h +++ b/src/search/SearchView.h @@ -22,9 +22,15 @@ private: ui::Button * previousButton; ui::Label * errorLabel; ui::Textbox * searchField; + ui::Label * infoLabel; + ui::Button * sortButton; + ui::Button * ownButton; void doSearch(); public: void NotifySaveListChanged(SearchModel * sender); + void NotifyPageChanged(SearchModel * sender); + void NotifySortChanged(SearchModel * sender); + void NotifyShowOwnChanged(SearchModel * sender); SearchView(); virtual ~SearchView(); void AttachController(SearchController * _c) { c = _c; } diff --git a/src/search/Thumbnail.h b/src/search/Thumbnail.h index 3b865ca58..6311a23bd 100644 --- a/src/search/Thumbnail.h +++ b/src/search/Thumbnail.h @@ -1,6 +1,7 @@ #ifndef THUMBNAIL_H #define THUMBNAIL_H +#include #include "Graphics.h" #include "interface/Point.h"