#include #include #include "SaveButton.h" #include "client/SaveInfo.h" #include "graphics/Graphics.h" #include "Engine.h" #include "client/ThumbnailBroker.h" #include "simulation/SaveRenderer.h" #include "Format.h" #include "ContextMenu.h" #include "Keys.h" namespace ui { SaveButton::SaveButton(Point position, Point size, SaveInfo * save): Component(position, size), file(NULL), save(save), thumbnail(NULL), isMouseInside(false), isButtonDown(false), actionCallback(NULL), selectable(false), selected(false), waitingForThumb(false), isMouseInsideAuthor(false), isMouseInsideHistory(false), showVotes(false) { menu = new ContextMenu(this); menu->AddItem(ContextMenuItem("Open", 0, true)); menu->AddItem(ContextMenuItem("Select", 1, true)); menu->AddItem(ContextMenuItem("View History", 2, true)); menu->AddItem(ContextMenuItem("More by this user", 3, true)); if(save) { name = save->name; if(Graphics::textwidth((char *)name.c_str()) > Size.X) { int position = Graphics::textwidthx((char *)name.c_str(), Size.X - 22); name = name.erase(position, name.length()-position); name += "..."; } std::string votes, icon; int j; votes = format::NumberToString(save->GetVotesUp()-save->GetVotesDown()); icon += 0xBB; for (int j = 1; j < votes.length(); j++) icon += 0xBC; icon += 0xB9; icon += 0xBA; votesBackground = icon; for (std::string::iterator iter = icon.begin(), end = icon.end(); iter != end; ++iter) *iter -= 14; votesBackground2 = icon; for (std::string::iterator iter = votes.begin(), end = votes.end(); iter != end; ++iter) if(*iter != '-') *iter += 127; votesString = votes; int voteMax = std::max(save->GetVotesUp(),save->GetVotesDown()); if (voteMax) { if (voteMax < 34) { float ry = 33.0f/voteMax; if (voteMax<8) ry = ry/(8-voteMax); voteBarHeightUp = (int)(save->GetVotesUp()*ry)-1; voteBarHeightDown = (int)(save->GetVotesDown()*ry)-1; } else { float ry = voteMax/33.0f; voteBarHeightUp = (int)(save->GetVotesUp()/ry)-1; voteBarHeightDown = (int)(save->GetVotesDown()/ry)-1; } } else { voteBarHeightUp = 0; voteBarHeightDown = 0; } } } SaveButton::SaveButton(Point position, Point size, SaveFile * file): Component(position, size), save(NULL), file(file), thumbnail(NULL), isMouseInside(false), isButtonDown(false), actionCallback(NULL), selectable(false), selected(false), wantsDraw(false), waitingForThumb(false), isMouseInsideAuthor(false), isMouseInsideHistory(false), showVotes(false) { if(file) { name = file->GetDisplayName(); if(Graphics::textwidth((char *)name.c_str()) > Size.X) { int position = Graphics::textwidthx((char *)name.c_str(), Size.X - 22); name = name.erase(position, name.length()-position); name += "..."; } } } SaveButton::~SaveButton() { ThumbnailBroker::Ref().DetachThumbnailListener(this); if(thumbnail) delete thumbnail; if(actionCallback) delete actionCallback; if(save) delete save; if(file) delete file; } void SaveButton::OnThumbnailReady(Thumbnail * thumb) { if(thumb) { if(thumbnail) delete thumbnail; thumbnail = thumb; waitingForThumb = false; } } void SaveButton::Tick(float dt) { if(!thumbnail && !waitingForThumb) { if(save) { if(save->GetGameSave()) { waitingForThumb = true; ThumbnailBroker::Ref().RenderThumbnail(save->GetGameSave(), Size.X-3, Size.Y-25, this); } else if(save->GetID()) { waitingForThumb = true; ThumbnailBroker::Ref().RetrieveThumbnail(save->GetID(), save->GetVersion(), Size.X-3, Size.Y-25, this); } } else if(file && file->GetGameSave()) { waitingForThumb = true; ThumbnailBroker::Ref().RenderThumbnail(file->GetGameSave(), Size.X-3, Size.Y-25, this); } } } void SaveButton::Draw(const Point& screenPos) { Graphics * g = ui::Engine::Ref().g; float scaleFactor; ui::Point thumbBoxSize(0, 0); wantsDraw = true; if(selected && selectable) { g->fillrect(screenPos.X, screenPos.Y, Size.X, Size.Y, 100, 170, 255, 100); } if(thumbnail) { thumbBoxSize = ui::Point(thumbnail->Size.X, thumbnail->Size.Y); if(save && save->id) g->draw_image(thumbnail->Data, screenPos.X-3+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, thumbnail->Size.X, thumbnail->Size.Y, 255); else g->draw_image(thumbnail->Data, screenPos.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, thumbnail->Size.X, thumbnail->Size.Y, 255); } else { scaleFactor = (Size.Y-25)/((float)YRES); thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor); } if(save) { if(save->id) { if(isMouseInside) { g->drawrect(screenPos.X-3+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, thumbBoxSize.X, thumbBoxSize.Y, 210, 230, 255, 255); g->drawrect(screenPos.X-4+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 7, thumbBoxSize.Y, 210, 230, 255, 255); } else { 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-4+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 7, thumbBoxSize.Y, 180, 180, 180, 255); } g->fillrect(screenPos.X-3+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+1+(Size.Y-20-thumbBoxSize.Y)/2, 5, (thumbBoxSize.Y+1)/2-1, 0, 107, 10, 255); g->fillrect(screenPos.X-3+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-20)/2, 5, thumbBoxSize.Y/2-1, 107, 10, 0, 255); g->fillrect(screenPos.X-2+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-20)/2-voteBarHeightUp, 3, voteBarHeightUp, 57, 187, 57, 255); //green g->fillrect(screenPos.X-2+thumbBoxSize.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-20)/2, 3, voteBarHeightDown, 187, 57, 57, 255); //red } else { if(isMouseInside) g->drawrect(screenPos.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, thumbBoxSize.X, thumbBoxSize.Y, 210, 230, 255, 255); else g->drawrect(screenPos.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, thumbBoxSize.X, thumbBoxSize.Y, 180, 180, 180, 255); } if(isMouseInside && !isMouseInsideAuthor) g->drawtext(screenPos.X+(Size.X-Graphics::textwidth((char *)name.c_str()))/2, screenPos.Y+Size.Y - 21, name, 255, 255, 255, 255); else g->drawtext(screenPos.X+(Size.X-Graphics::textwidth((char *)name.c_str()))/2, screenPos.Y+Size.Y - 21, name, 180, 180, 180, 255); if(isMouseInsideAuthor) g->drawtext(screenPos.X+(Size.X-Graphics::textwidth((char *)save->userName.c_str()))/2, screenPos.Y+Size.Y - 10, save->userName, 200, 230, 255, 255); else g->drawtext(screenPos.X+(Size.X-Graphics::textwidth((char *)save->userName.c_str()))/2, screenPos.Y+Size.Y - 10, save->userName, 100, 130, 160, 255); if (showVotes)// && !isMouseInside) { int x = screenPos.X-7+(Size.X-thumbBoxSize.X)/2+thumbBoxSize.X-Graphics::textwidth(votesBackground.c_str()); int y = screenPos.Y-23+(Size.Y-thumbBoxSize.Y)/2+thumbBoxSize.Y; g->drawtext(x, y, votesBackground, 16, 72, 16, 255); g->drawtext(x, y, votesBackground2, 192, 192, 192, 255); g->drawtext(x+3, y, votesString, 255, 255, 255, 255); } if (isMouseInsideHistory && showVotes) { int x = screenPos.X; int y = screenPos.Y-15+(Size.Y-thumbBoxSize.Y)/2+thumbBoxSize.Y; g->fillrect(x+1, y+1, 7, 8, 255, 255, 255, 255); if (isMouseInsideHistory) { g->drawtext(x, y, "\xA6", 200, 100, 80, 255); } else { g->drawtext(x, y, "\xA6", 160, 70, 50, 255); } } if (!save->GetPublished()) { g->drawtext(screenPos.X, screenPos.Y-2, "\xCD", 255, 255, 255, 255); g->drawtext(screenPos.X, screenPos.Y-2, "\xCE", 212, 151, 81, 255); } } if(file) { if(isMouseInside) g->drawrect(screenPos.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, thumbBoxSize.X, thumbBoxSize.Y, 210, 230, 255, 255); else g->drawrect(screenPos.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, thumbBoxSize.X, thumbBoxSize.Y, 180, 180, 180, 255); if(isMouseInside) { g->drawtext(screenPos.X+(Size.X-Graphics::textwidth((char *)name.c_str()))/2, screenPos.Y+Size.Y - 21, name, 255, 255, 255, 255); } else { g->drawtext(screenPos.X+(Size.X-Graphics::textwidth((char *)name.c_str()))/2, screenPos.Y+Size.Y - 21, name, 180, 180, 180, 255); } } if(isMouseInside && selectable) { g->clearrect(screenPos.X+(Size.X-20), screenPos.Y+6, 14, 14); g->drawrect(screenPos.X+(Size.X-20), screenPos.Y+6, 14, 14, 255, 255, 255, 255); if(selected) g->fillrect(screenPos.X+(Size.X-18), screenPos.Y+8, 10, 10, 255, 255, 255, 255); } } void SaveButton::OnMouseUnclick(int x, int y, unsigned int button) { if(button != 1) { return; //left click only! } if(x>=Size.X-20 && y>=6 && y<=20 && x<=Size.X-6 && selectable) { selected = !selected; DoSelection(); return; } if(isButtonDown) { isButtonDown = false; if(isMouseInsideAuthor) DoAuthorAction(); else if(isMouseInsideHistory) DoHistoryAction(); else DoAction(); } } void SaveButton::OnContextMenuAction(int item) { switch(item) { case 0: DoAction(); break; case 1: selected = !selected; DoSelection(); break; case 2: DoHistoryAction(); break; case 3: DoAuthorAction(); break; } } void SaveButton::OnMouseClick(int x, int y, unsigned int button) { if(button == BUTTON_RIGHT) { if(menu) menu->Show(GetScreenPos() + ui::Point(x, y)); } else { isButtonDown = true; if(button !=1 && selectable) { selected = !selected; DoSelection(); } } } void SaveButton::OnMouseMovedInside(int x, int y, int dx, int dy) { if(y > Size.Y-11) isMouseInsideAuthor = true; else isMouseInsideAuthor = false; if(showVotes && y > Size.Y-29 && y < Size.Y - 18 && x > 0 && x < 9) isMouseInsideHistory = true; else isMouseInsideHistory = false; } void SaveButton::OnMouseEnter(int x, int y) { isMouseInside = true; } void SaveButton::OnMouseLeave(int x, int y) { isMouseInside = false; isMouseInsideAuthor = false; isMouseInsideHistory = false; } void SaveButton::DoHistoryAction() { if(actionCallback) actionCallback->HistoryActionCallback(this); } void SaveButton::DoAuthorAction() { if(actionCallback) actionCallback->AuthorActionCallback(this); } void SaveButton::DoAction() { if(actionCallback) actionCallback->ActionCallback(this); } void SaveButton::DoSelection() { if(menu) { if(selected) menu->SetItem(1, "Deselect"); else menu->SetItem(1, "Select"); } if(selectable && actionCallback) actionCallback->SelectedCallback(this); } void SaveButton::SetActionCallback(SaveButtonAction * action) { actionCallback = action; } } /* namespace ui */