Comments on save preview and some minor changes for vote bars

This commit is contained in:
Simon Robertshaw 2012-02-11 16:08:59 +00:00
parent 54741c79ef
commit 9f7b06ff47
16 changed files with 413 additions and 14 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
*.a
*.la
*~
*.pref

View File

@ -422,6 +422,52 @@ Thumbnail * Client::GetPreview(int saveID, int saveDate)
}
}
std::vector<Comment*> * Client::GetComments(int saveID, int start, int count)
{
lastError = "";
std::vector<Comment*> * commentArray = new std::vector<Comment*>();
std::stringstream urlStream;
char * data;
int dataStatus, dataLength;
urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID << "&Mode=Comments&Start=" << start << "&Count=" << count;
data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
if(dataStatus == 200 && data)
{
try
{
std::istringstream dataStream(data);
json::Array commentsArray;
json::Reader::Read(commentsArray, dataStream);
for(int j = 0; j < commentsArray.Size(); j++)
{
json::Number tempUserID = commentsArray[j]["UserID"];
json::String tempUsername = commentsArray[j]["Username"];
json::String tempComment = commentsArray[j]["Text"];
commentArray->push_back(
new Comment(
tempUserID.Value(),
tempUsername.Value(),
tempComment.Value()
)
);
}
}
catch (json::Exception &e)
{
lastError = "Could not read response";
}
}
else
{
lastError = http_ret_text(dataStatus);
}
if(data)
free(data);
return commentArray;
}
std::vector<Save*> * Client::SearchSaves(int start, int count, string query, string sort, int & resultCount)
{
lastError = "";

View File

@ -7,6 +7,7 @@
#include "Config.h"
#include "HTTP.h"
#include "preview/Comment.h"
#include "search/Thumbnail.h"
#include "search/Save.h"
#include "Singleton.h"
@ -52,6 +53,7 @@ public:
LoginStatus Login(string username, string password, User & user);
void ClearThumbnailRequests();
std::vector<Save*> * SearchSaves(int start, int count, string query, string sort, int & resultCount);
std::vector<Comment*> * GetComments(int saveID, int start, int count);
Thumbnail * GetPreview(int saveID, int saveDate);
Thumbnail * GetThumbnail(int saveID, int saveDate);
Save * GetSave(int saveID, int saveDate);

View File

@ -11,6 +11,7 @@ namespace ui
{
class Label : public Component
{
protected:
std::string text;
ui::Point textPosition;
HorizontalAlignment textHAlign;
@ -23,8 +24,8 @@ namespace ui
//Label(std::string labelText);
virtual ~Label();
void TextPosition();
void SetText(std::string text);
virtual void TextPosition();
virtual void SetText(std::string text);
HorizontalAlignment GetHAlignment() { return textHAlign; }
VerticalAlignment GetVAlignment() { return textVAlign; }
void SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign) { textHAlign = hAlign; textVAlign = vAlign; TextPosition(); }

View File

@ -103,8 +103,8 @@ void SaveButton::Draw(const Point& screenPos)
g->drawrect(screenPos.X-3+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, thumbBoxSize.X, thumbBoxSize.Y, 180, 180, 180, 255);
g->drawrect(screenPos.X-3+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 6, thumbBoxSize.Y, 180, 180, 180, 255);
int voteBar = max(10.0f, ((float)(thumbBoxSize.Y))*voteRatio);
g->fillrect(screenPos.X-3+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(thumbBoxSize.Y-voteBar)+(Size.Y-21-thumbBoxSize.Y)/2, 6, voteBar, voteColour.Red, voteColour.Green, voteColour.Blue, 255);
int voteBar = max(10.0f, ((float)(thumbBoxSize.Y-2))*voteRatio);
g->fillrect(1+screenPos.X-3+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, 1+(screenPos.Y-2)+(thumbBoxSize.Y-voteBar)+(Size.Y-21-thumbBoxSize.Y)/2, 4, voteBar, voteColour.Red, voteColour.Green, voteColour.Blue, 255);
}
else
{

36
src/interface/Spinner.cpp Normal file
View File

@ -0,0 +1,36 @@
/*
* Spinner.cpp
*
* Created on: Feb 11, 2012
* Author: Simon
*/
#include <math.h>
#include <iostream>
#include "Spinner.h"
using namespace ui;
Spinner::Spinner(Point position, Point size):
Component(position, size), cValue(0)
{
}
void Spinner::Tick(float dt)
{
cValue += 0.05f;
}
void Spinner::Draw(const Point& screenPos)
{
Graphics * g = ui::Engine::Ref().g;
int baseX = screenPos.X+(Size.X/2);
int baseY = screenPos.Y+(Size.Y/2);
for(float t = 0.0f; t < 1.0f; t+=0.05f)
{
g->drawblob(baseX+(sin(cValue+t)*(Size.X/2)), baseY+(cos(cValue+t)*(Size.X/2)), t*255, t*255, t*255);
}
}
Spinner::~Spinner()
{
}

29
src/interface/Spinner.h Normal file
View File

@ -0,0 +1,29 @@
/*
* Spinner.h
*
* Created on: Feb 11, 2012
* Author: Simon
*/
#ifndef SPINNER_H_
#define SPINNER_H_
#include "Component.h"
namespace ui
{
class Spinner: public Component
{
float cValue;
public:
Spinner(Point position, Point size);
virtual void Tick(float dt);
virtual void Draw(const Point& screenPos);
virtual ~Spinner();
};
}
#endif /* SPINNER_H_ */

View File

@ -0,0 +1,76 @@
/*
* Textblock.cpp
*
* Created on: Jan 29, 2012
* Author: Simon
*/
#include <iostream>
#include "Textblock.h"
using namespace ui;
Textblock::Textblock(Point position, Point size, std::string textboxText):
Label(position, size, textboxText)
{
if(size.Y==-1)
autoHeight = true;
else
autoHeight = false;
updateMultiline();
}
void Textblock::SetText(std::string text)
{
this->text = text;
updateMultiline();
}
void Textblock::updateMultiline()
{
char * rawText = (char*)malloc(text.length()+1);
memcpy(rawText, text.c_str(), text.length());
rawText[text.length()] = 0;
int lines = 1;
int currentWidth = 0;
char * lastSpace = NULL;
char * currentWord = rawText;
char * nextSpace;
while(true)
{
nextSpace = strchr(currentWord+1, ' ');
if(nextSpace)
nextSpace[0] = 0;
int width = Graphics::textwidth(currentWord);
if(width+currentWidth > Size.X-6)
{
currentWidth = width;
currentWord[0] = '\n';
lines++;
}
else
currentWidth += width;
if(nextSpace)
nextSpace[0] = ' ';
if(!(currentWord = strchr(currentWord+1, ' ')))
break;
}
if(autoHeight)
{
Size.Y = lines*12;
}
textLines = rawText;
}
void Textblock::Draw(const Point &screenPos)
{
Graphics * g = ui::Engine::Ref().g;
//g->drawrect(screenPos.X, screenPos.Y, Size.X, Size.Y, textColour.Red, textColour.Green, textColour.Blue, 255);
g->drawtext(screenPos.X+3, screenPos.Y+3, textLines, textColour.Red, textColour.Green, textColour.Blue, 255);
}
Textblock::~Textblock() {
// TODO Auto-generated destructor stub
}

33
src/interface/Textblock.h Normal file
View File

@ -0,0 +1,33 @@
/*
* Textblock.h
*
* Created on: Jan 29, 2012
* Author: Simon
*/
#ifndef TEXTBLOCK_H_
#define TEXTBLOCK_H_
#include <vector>
#include <string>
#include <sstream>
#include "Label.h"
namespace ui
{
class Textblock: public ui::Label
{
bool autoHeight;
void updateMultiline();
std::string textLines;
public:
Textblock(Point position, Point size, std::string textboxText);
virtual void TextPosition() {}
virtual void SetText(std::string text);
virtual void Draw(const Point& screenPos);
virtual ~Textblock();
};
}
#endif /* TEXTBLOCK_H_ */

24
src/preview/Comment.h Normal file
View File

@ -0,0 +1,24 @@
/*
* Comment.h
*
* Created on: Feb 11, 2012
* Author: Simon
*/
#ifndef COMMENT_H_
#define COMMENT_H_
class Comment
{
public:
int authorID;
std::string authorName;
std::string comment;
Comment(int userID, std::string username, std::string commentText):
authorID(userID), authorName(username), comment(commentText)
{
}
};
#endif /* COMMENT_H_ */

View File

@ -11,11 +11,14 @@
PreviewModel::PreviewModel():
save(NULL),
savePreview(NULL),
saveComments(NULL),
doOpen(false),
updateSavePreviewWorking(false),
updateSavePreviewFinished(false),
updateSaveInfoWorking(false),
updateSaveInfoFinished(false)
updateSaveInfoFinished(false),
updateSaveCommentsWorking(false),
updateSaveCommentsFinished(false)
{
// TODO Auto-generated constructor stub
@ -31,6 +34,11 @@ void * PreviewModel::updateSavePreviewTHelper(void * obj)
return ((PreviewModel*)obj)->updateSavePreviewT();
}
void * PreviewModel::updateSaveCommentsTHelper(void * obj)
{
return ((PreviewModel*)obj)->updateSaveCommentsT();
}
void * PreviewModel::updateSaveInfoT()
{
Save * tempSave = Client::Ref().GetSave(tSaveID, tSaveDate);
@ -45,15 +53,38 @@ void * PreviewModel::updateSavePreviewT()
return tempThumb;
}
void * PreviewModel::updateSaveCommentsT()
{
std::vector<Comment*> * tempComments = Client::Ref().GetComments(tSaveID, 0, 10);
updateSaveCommentsFinished = true;
return tempComments;
}
void PreviewModel::UpdateSave(int saveID, int saveDate)
{
this->tSaveID = saveID;
this->tSaveDate = saveDate;
save = NULL;
savePreview = NULL;
if(save)
{
delete save;
save = NULL;
}
if(savePreview)
{
delete savePreview;
savePreview = NULL;
}
if(saveComments)
{
for(int i = 0; i < saveComments->size(); i++)
delete saveComments->at(i);
delete saveComments;
saveComments = NULL;
}
notifyPreviewChanged();
notifySaveChanged();
notifySaveCommentsChanged();
if(!updateSavePreviewWorking)
{
@ -68,6 +99,13 @@ void PreviewModel::UpdateSave(int saveID, int saveDate)
updateSaveInfoFinished = false;
pthread_create(&updateSaveInfoThread, 0, &PreviewModel::updateSaveInfoTHelper, this);
}
if(!updateSaveCommentsWorking)
{
updateSaveCommentsWorking = true;
updateSaveCommentsFinished = false;
pthread_create(&updateSaveCommentsThread, 0, &PreviewModel::updateSaveCommentsTHelper, this);
}
}
void PreviewModel::SetDoOpen(bool doOpen)
@ -90,6 +128,11 @@ Save * PreviewModel::GetSave()
return save;
}
std::vector<Comment*> * PreviewModel::GetComments()
{
return saveComments;
}
void PreviewModel::notifyPreviewChanged()
{
for(int i = 0; i < observers.size(); i++)
@ -106,6 +149,14 @@ void PreviewModel::notifySaveChanged()
}
}
void PreviewModel::notifySaveCommentsChanged()
{
for(int i = 0; i < observers.size(); i++)
{
observers[i]->NotifyCommentsChanged(this);
}
}
void PreviewModel::AddObserver(PreviewView * observer) {
observers.push_back(observer);
observer->NotifyPreviewChanged(this);
@ -118,6 +169,11 @@ void PreviewModel::Update()
{
if(updateSavePreviewFinished)
{
if(savePreview)
{
delete savePreview;
savePreview = NULL;
}
updateSavePreviewWorking = false;
pthread_join(updateSavePreviewThread, (void**)(&savePreview));
notifyPreviewChanged();
@ -128,11 +184,33 @@ void PreviewModel::Update()
{
if(updateSaveInfoFinished)
{
if(save)
{
delete save;
save = NULL;
}
updateSaveInfoWorking = false;
pthread_join(updateSaveInfoThread, (void**)(&save));
notifySaveChanged();
}
}
if(updateSaveCommentsWorking)
{
if(updateSaveCommentsFinished)
{
if(saveComments)
{
for(int i = 0; i < saveComments->size(); i++)
delete saveComments->at(i);
delete saveComments;
saveComments = NULL;
}
updateSaveCommentsWorking = false;
pthread_join(updateSaveCommentsThread, (void**)(&saveComments));
notifySaveCommentsChanged();
}
}
}
PreviewModel::~PreviewModel() {

View File

@ -12,6 +12,7 @@
#include <pthread.h>
#include "PreviewView.h"
#include "search/Save.h"
#include "preview/Comment.h"
#include "search/Thumbnail.h"
using namespace std;
@ -22,8 +23,10 @@ class PreviewModel {
vector<PreviewView*> observers;
Save * save;
Thumbnail * savePreview;
std::vector<Comment*> * saveComments;
void notifyPreviewChanged();
void notifySaveChanged();
void notifySaveCommentsChanged();
//Background retrieval
int tSaveID;
@ -40,10 +43,17 @@ class PreviewModel {
pthread_t updateSaveInfoThread;
static void * updateSaveInfoTHelper(void * obj);
void * updateSaveInfoT();
bool updateSaveCommentsWorking;
volatile bool updateSaveCommentsFinished;
pthread_t updateSaveCommentsThread;
static void * updateSaveCommentsTHelper(void * obj);
void * updateSaveCommentsT();
public:
PreviewModel();
Thumbnail * GetPreview();
Save * GetSave();
std::vector<Comment*> * GetComments();
void AddObserver(PreviewView * observer);
void UpdateSave(int saveID, int saveDate);
bool GetDoOpen();

View File

@ -5,6 +5,7 @@
* Author: Simon
*/
#include <vector>
#include "PreviewView.h"
#include "interface/Point.h"
#include "interface/Window.h"
@ -51,6 +52,11 @@ PreviewView::PreviewView():
saveNameLabel->SetAlignment(AlignLeft, AlignBottom);
AddComponent(saveNameLabel);
saveDescriptionTextblock = new ui::Textblock(ui::Point(5, (YRES/2)+15+14+17), ui::Point((XRES/2)-10, Size.Y-((YRES/2)+15+14+17)-21), "");
saveDescriptionTextblock->SetAlignment(AlignLeft, AlignTop);
saveDescriptionTextblock->SetTextColour(ui::Colour(180, 180, 180));
AddComponent(saveDescriptionTextblock);
authorDateLabel = new ui::Label(ui::Point(5, (YRES/2)+15+14), ui::Point(100, 16), "");
authorDateLabel->SetAlignment(AlignLeft, AlignBottom);
AddComponent(authorDateLabel);
@ -78,13 +84,13 @@ void PreviewView::OnDraw()
if(!votesUp && !votesDown)
return;
else
factor = (float)(((float)(XRES/2))/((float)(votesUp+votesDown)));
g->fillrect(Position.X, Position.Y+YRES/2, XRES/2, 10, 200, 50, 50, 255);
g->fillrect(Position.X, Position.Y+YRES/2, (int)(((float)votesUp)*factor), 10, 50, 200, 50, 255);
g->fillrect(Position.X, Position.Y+(YRES/2), 14, 10, 0, 0, 0, 100);
g->fillrect(Position.X+(XRES/2)-14, Position.Y+(YRES/2), 14, 10, 0, 0, 0, 100);
g->draw_icon(Position.X+2, Position.Y+(YRES/2)+2, IconVoteUp);
g->draw_icon(Position.X+(XRES/2)-12, Position.Y+(YRES/2), IconVoteDown);
factor = (float)(((float)(XRES/2)-2)/((float)(votesUp+votesDown)));
g->fillrect(1+Position.X, 1+Position.Y+YRES/2, (XRES/2)-2, 8, 200, 50, 50, 255);
g->fillrect(1+Position.X, 1+Position.Y+YRES/2, (int)(((float)votesUp)*factor), 8, 50, 200, 50, 255);
g->fillrect(1+Position.X, 1+Position.Y+(YRES/2), 14, 8, 0, 0, 0, 100);
g->fillrect(Position.X+(XRES/2)-15, 1+Position.Y+(YRES/2), 14, 8, 0, 0, 0, 100);
g->draw_icon(1+Position.X+2, Position.Y+(YRES/2)+2, IconVoteUp);
g->draw_icon(Position.X+(XRES/2)-12, Position.Y+(YRES/2)-1, IconVoteDown);
}
void PreviewView::OnTick(float dt)
@ -107,6 +113,7 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender)
votesDown = save->votesDown;
saveNameLabel->SetText(save->name);
authorDateLabel->SetText("\bgAuthor:\bw " + save->userName + " \bgDate:\bw ");
saveDescriptionTextblock->SetText(save->Description);
}
else
{
@ -114,6 +121,49 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender)
votesDown = 0;
saveNameLabel->SetText("");
authorDateLabel->SetText("");
saveDescriptionTextblock->SetText("");
}
}
void PreviewView::NotifyCommentsChanged(PreviewModel * sender)
{
for(int i = 0; i < commentComponents.size(); i++)
{
RemoveComponent(commentComponents[i]);
delete commentComponents[i];
}
commentComponents.clear();
int currentY = 0;
ui::Label * tempUsername;
ui::Textblock * tempComment;
std::vector<Comment*> * tempComments = sender->GetComments();
if(tempComments)
{
for(int i = 0; i < tempComments->size(); i++)
{
tempUsername = new ui::Label(ui::Point((XRES/2) + 5, currentY+5), ui::Point(Size.X-((XRES/2) + 10), 16), tempComments->at(i)->authorName);
tempUsername->SetAlignment(AlignLeft, AlignBottom);
currentY += 16;
tempComment = new ui::Textblock(ui::Point((XRES/2) + 5, currentY+5), ui::Point(Size.X-((XRES/2) + 10), -1), tempComments->at(i)->comment);
tempComment->SetAlignment(AlignLeft, AlignTop);
tempComment->SetTextColour(ui::Colour(180, 180, 180));
currentY += tempComment->Size.Y+4;
if(currentY > Size.Y)
{
delete tempUsername;
delete tempComment;
break;
}
else
{
commentComponents.push_back(tempComment);
AddComponent(tempComment);
commentComponents.push_back(tempUsername);
AddComponent(tempUsername);
}
}
}
}

View File

@ -7,12 +7,15 @@
#ifndef PREVIEWVIEW_H_
#define PREVIEWVIEW_H_
#include <vector>
#include "interface/Window.h"
#include "preview/PreviewController.h"
#include "preview/PreviewModel.h"
#include "interface/Button.h"
#include "search/Thumbnail.h"
#include "interface/Label.h"
#include "interface/Textblock.h"
class PreviewModel;
class PreviewController;
@ -23,6 +26,8 @@ class PreviewView: public ui::Window {
ui::Button * browserOpenButton;
ui::Label * saveNameLabel;
ui::Label * authorDateLabel;
ui::Textblock * saveDescriptionTextblock;
std::vector<ui::Component*> commentComponents;
int votesUp;
int votesDown;
public:
@ -30,6 +35,7 @@ public:
PreviewView();
void NotifyPreviewChanged(PreviewModel * sender);
void NotifySaveChanged(PreviewModel * sender);
void NotifyCommentsChanged(PreviewModel * sender);
virtual void OnDraw();
virtual void OnTick(float dt);
virtual void OnMouseDown(int x, int y, unsigned button);

View File

@ -91,6 +91,9 @@ SearchView::SearchView():
AddComponent(searchField);
AddComponent(infoLabel);
loadingSpinner = new ui::Spinner(ui::Point(((XRES+BARSIZE)/2)-12, ((YRES+MENUSIZE)/2)+12), ui::Point(24, 24));
AddComponent(loadingSpinner);
ui::Label * searchPrompt = new ui::Label(ui::Point(10, 10), ui::Point(50, 16), "Search:");
searchPrompt->SetAlignment(AlignLeft, AlignBottom);
AddComponent(searchPrompt);
@ -172,6 +175,7 @@ void SearchView::NotifySaveListChanged(SearchModel * sender)
if(!sender->GetSavesLoaded())
{
errorLabel->SetText("Loading...");
loadingSpinner->Visible = true;
}
else
{
@ -183,6 +187,7 @@ void SearchView::NotifySaveListChanged(SearchModel * sender)
}
else
{
loadingSpinner->Visible = false;
if(errorLabel)
{
RemoveComponent(errorLabel);

View File

@ -6,6 +6,7 @@
#include "interface/SaveButton.h"
#include "interface/Button.h"
#include "interface/Label.h"
#include "interface/Spinner.h"
#include "interface/Textbox.h"
using namespace std;
@ -25,6 +26,7 @@ private:
ui::Label * infoLabel;
ui::Button * sortButton;
ui::Button * ownButton;
ui::Spinner * loadingSpinner;
void doSearch();
public:
void NotifySaveListChanged(SearchModel * sender);