Add and remove tags.\nBrings to light an interesting issue with adding or removing UI components within component Event handlers

This commit is contained in:
Simon Robertshaw 2012-03-22 22:12:16 +00:00
parent 23873eae71
commit 63af6abd29
8 changed files with 244 additions and 7 deletions

View File

@ -676,3 +676,101 @@ Thumbnail * Client::GetThumbnail(int saveID, int saveDate)
//http_async_req_start(http, urlStream.str().c_str(), NULL, 0, 1);
return NULL;
}
std::vector<string> * Client::RemoveTag(int saveID, string tag)
{
lastError = "";
std::vector<string> * tags = NULL;
std::stringstream urlStream;
char * data = NULL;
int dataStatus, dataLength;
urlStream << "http://" << SERVER << "/Browse/EditTag.json?Op=delete&ID=" << saveID << "&Tag=" << tag;
if(authUser.ID)
{
std::stringstream userIDStream;
userIDStream << authUser.ID;
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
}
else
{
lastError = "Not authenticated";
return NULL;
}
if(dataStatus == 200 && data)
{
try
{
std::istringstream dataStream(data);
json::Array tagsArray;
json::Reader::Read(tagsArray, dataStream);
tags = new std::vector<string>();
for(int j = 0; j < tagsArray.Size(); j++)
{
json::String tempTag = tagsArray[j];
tags->push_back(tempTag.Value());
}
}
catch (json::Exception &e)
{
lastError = "Could not read response";
}
}
else
{
lastError = http_ret_text(dataStatus);
}
if(data)
free(data);
return tags;
}
std::vector<string> * Client::AddTag(int saveID, string tag)
{
lastError = "";
std::vector<string> * tags = NULL;
std::stringstream urlStream;
char * data = NULL;
int dataStatus, dataLength;
urlStream << "http://" << SERVER << "/Browse/EditTag.json?Op=add&ID=" << saveID << "&Tag=" << tag;
if(authUser.ID)
{
std::stringstream userIDStream;
userIDStream << authUser.ID;
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
}
else
{
lastError = "Not authenticated";
return NULL;
}
if(dataStatus == 200 && data)
{
try
{
std::istringstream dataStream(data);
json::Array tagsArray;
json::Reader::Read(tagsArray, dataStream);
tags = new std::vector<string>();
for(int j = 0; j < tagsArray.Size(); j++)
{
json::String tempTag = tagsArray[j];
tags->push_back(tempTag.Value());
}
}
catch (json::Exception &e)
{
lastError = "Could not read response";
}
}
else
{
lastError = http_ret_text(dataStatus);
}
if(data)
free(data);
return tags;
}

View File

@ -59,6 +59,8 @@ public:
Save * GetSave(int saveID, int saveDate);
void SetAuthUser(User user);
User GetAuthUser();
std::vector<string> * RemoveTag(int saveID, string tag);
std::vector<string> * AddTag(int saveID, string tag);
std::string GetLastError() {
return lastError;
}

View File

@ -29,6 +29,17 @@ Save * TagsController::GetSave()
return tagsModel->GetSave();
}
void TagsController::RemoveTag(string tag)
{
tagsModel->RemoveTag(tag);
}
void TagsController::AddTag(string tag)
{
tagsModel->AddTag(tag);
}
void TagsController::Exit()
{
if(ui::Engine::Ref().GetWindow() == tagsView)

View File

@ -23,6 +23,8 @@ public:
TagsController(ControllerCallback * callback, Save * save);
TagsView * GetView() {return tagsView;}
Save * GetSave();
void RemoveTag(string tag);
void AddTag(string tag);
void Exit();
virtual ~TagsController();
};

View File

@ -7,6 +7,7 @@
#include "TagsModel.h"
#include "TagsView.h"
#include "client/Client.h"
TagsModel::TagsModel():
save(NULL)
@ -26,6 +27,44 @@ Save * TagsModel::GetSave()
return save;
}
void TagsModel::RemoveTag(string tag)
{
if(save)
{
std::vector<string> * tags = Client::Ref().RemoveTag(save->GetID(), tag);
if(tags)
{
save->SetTags(vector<string>(*tags));
notifyTagsChanged();
delete tags;
}
else
{
lastError = Client::Ref().GetLastError();
notifyError();
}
}
}
void TagsModel::AddTag(string tag)
{
if(save)
{
std::vector<string> * tags = Client::Ref().AddTag(save->GetID(), tag);
if(tags)
{
save->SetTags(vector<string>(*tags));
notifyTagsChanged();
delete tags;
}
else
{
lastError = Client::Ref().GetLastError();
notifyError();
}
}
}
void TagsModel::AddObserver(TagsView * observer)
{
observers.push_back(observer);
@ -40,6 +79,14 @@ void TagsModel::notifyTagsChanged()
}
}
void TagsModel::notifyError()
{
for(int i = 0; i < observers.size(); i++)
{
observers[i]->NotifyError(this);
}
}
TagsModel::~TagsModel() {
// TODO Auto-generated destructor stub
}

View File

@ -14,13 +14,18 @@
class TagsView;
class TagsModel {
Save * save;
string lastError;
std::vector<TagsView*> observers;
void notifyTagsChanged();
void notifyError();
public:
TagsModel();
void AddObserver(TagsView * observer);
void SetSave(Save * save);
void RemoveTag(string tag);
void AddTag(string tag);
Save * GetSave();
string GetLastError(){ return lastError; }
virtual ~TagsModel();
};

View File

@ -5,18 +5,38 @@
* Author: Simon
*/
#include "client/Client.h"
#include "TagsView.h"
#include "dialogues/ErrorMessage.h"
#include "TagsController.h"
#include "TagsModel.h"
TagsView::TagsView():
ui::Window(ui::Point(-1, -1), ui::Point(200, 300))
ui::Window(ui::Point(-1, -1), ui::Point(195, 250))
{
submitButton = new ui::Button(ui::Point(Size.X-56, Size.Y-24), ui::Point(50, 16));
AddComponent(submitButton);
tagInput = new ui::Textbox(ui::Point(6, Size.Y-24), ui::Point(Size.X-80, 16), "");
class CloseAction : public ui::ButtonAction
{
TagsView * v;
public:
CloseAction(TagsView * _v) { v = _v; }
void ActionCallback(ui::Button * sender)
{
v->c->Exit();
}
};
closeButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(195, 16), "Close");
closeButton->SetAlignment(AlignLeft, AlignTop);
closeButton->SetActionCallback(new CloseAction(this));
AddComponent(closeButton);
tagInput = new ui::Textbox(ui::Point(8, Size.Y-40), ui::Point(Size.X-16, 16), "");
AddComponent(tagInput);
title = new ui::Label(ui::Point(5, 5), ui::Point(185, 16), "Manage tags:");
title->SetAlignment(AlignLeft, AlignTop);
AddComponent(title);
}
void TagsView::OnDraw()
@ -26,6 +46,11 @@ void TagsView::OnDraw()
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255);
}
void TagsView::NotifyError(TagsModel * sender)
{
new ErrorMessage("Error", sender->GetLastError());
}
void TagsView::NotifyTagsChanged(TagsModel * sender)
{
for(int i = 0; i < tags.size(); i++)
@ -35,17 +60,61 @@ void TagsView::NotifyTagsChanged(TagsModel * sender)
}
tags.clear();
class DeleteTagAction : public ui::ButtonAction
{
TagsView * v;
string tag;
public:
DeleteTagAction(TagsView * _v, string tag) { v = _v; this->tag = tag; }
void ActionCallback(ui::Button * sender)
{
v->c->RemoveTag(tag);
}
};
if(sender->GetSave())
{
for(int i = 0; i < sender->GetSave()->GetTags().size(); i++)
{
ui::Label * tempLabel = new ui::Label(ui::Point(5, 10*i), ui::Point(50, 16), sender->GetSave()->GetTags()[i]);
ui::Label * tempLabel = new ui::Label(ui::Point(35, 35+(16*i)), ui::Point(120, 16), sender->GetSave()->GetTags()[i]);
tempLabel->SetAlignment(AlignLeft, AlignMiddle);
tags.push_back(tempLabel);
AddComponent(tempLabel);
if(sender->GetSave()->GetUserName()==Client::Ref().GetAuthUser().Username)
{
ui::Button * tempButton = new ui::Button(ui::Point(15, 35+(16*i)), ui::Point(14, 14), "x");
tempButton->SetAlignment(AlignCentre, AlignMiddle);
tempButton->SetActionCallback(new DeleteTagAction(this, sender->GetSave()->GetTags()[i]));
tags.push_back(tempButton);
AddComponent(tempButton);
}
}
}
}
void TagsView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt)
{
switch(key)
{
/*case KEY_TAB:
if(IsFocused(usernameField))
FocusComponent(passwordField);
else
FocusComponent(usernameField);
break;*/
case KEY_ENTER:
case KEY_RETURN:
if(IsFocused(tagInput))
{
c->AddTag(tagInput->GetText());
tagInput->SetText("");
}
break;
}
}
TagsView::~TagsView() {
// TODO Auto-generated destructor stub
}

View File

@ -18,13 +18,16 @@ class TagsController;
class TagsModel;
class TagsView: public ui::Window {
TagsController * c;
ui::Button * submitButton;
ui::Button * closeButton;
ui::Label * title;
ui::Textbox * tagInput;
std::vector<ui::Label*> tags;
std::vector<ui::Component*> tags;
public:
TagsView();
virtual void OnDraw();
void NotifyError(TagsModel * sender);
void AttachController(TagsController * c_) { c = c_; };
virtual void OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt);
void NotifyTagsChanged(TagsModel * sender);
virtual ~TagsView();
};