Local file browser + some more interesting things like Progress bar UI component

This commit is contained in:
Simon Robertshaw 2012-07-27 20:06:17 +01:00
parent f8ca8af387
commit 5befe5c25f
32 changed files with 790 additions and 79 deletions

View File

@ -19,6 +19,35 @@
#include <ApplicationServices/ApplicationServices.h>
#endif
std::string URLEscape(std::string source)
{
char * src = (char *)source.c_str();
char * dst = (char *)calloc((source.length()*3)+2, 1);
char *d;
unsigned char *s;
for (d=dst; *d; d++) ;
for (s=(unsigned char *)src; *s; s++)
{
if ((*s>='0' && *s<='9') ||
(*s>='a' && *s<='z') ||
(*s>='A' && *s<='Z'))
*(d++) = *s;
else
{
*(d++) = '%';
*(d++) = hex[*s>>4];
*(d++) = hex[*s&15];
}
}
*d = 0;
std::string finalString(dst);
free(dst);
return finalString;
}
#if defined(USE_SDL) && (defined(LIN32) || defined(LIN64)) && defined(SDL_VIDEO_DRIVER_X11)
#include <SDL/SDL_syswm.h>
SDL_SysWMinfo sdl_wminfo;
@ -212,35 +241,6 @@ void strcaturl(char *dst, char *src)
*d = 0;
}
std::string URLEscape(std::string source)
{
char * src = (char *)source.c_str();
char * dst = (char *)calloc((source.length()*3)+2, 1);
char *d;
unsigned char *s;
for (d=dst; *d; d++) ;
for (s=(unsigned char *)src; *s; s++)
{
if ((*s>='0' && *s<='9') ||
(*s>='a' && *s<='z') ||
(*s>='A' && *s<='Z'))
*(d++) = *s;
else
{
*(d++) = '%';
*(d++) = hex[*s>>4];
*(d++) = hex[*s&15];
}
}
*d = 0;
std::string finalString(dst);
free(dst);
return finalString;
}
void strappend(char *dst, char *src)
{
char *d;

View File

@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#if defined(WIN32) && !defined(__GNUC__)
#define x86_cpuid(func,af,bf,cf,df) \

View File

@ -207,7 +207,6 @@ int main(int argc, char * argv[])
//glScaled(2.0f, 2.0f, 1.0f);
#endif
ui::Engine::Ref().g = new Graphics();
//ui::Engine::Ref().g->AttachSDLSurface(SDLOpen());

View File

@ -22,13 +22,19 @@
#include "Misc.h"
#include "interface/Point.h"
#include "client/SaveInfo.h"
#include "ClientListener.h"
#include "Update.h"
extern "C"
{
#if defined(WIN32) && !defined(__GNUC__)
#include <io.h>
#else
#include <dirent.h>
#endif
}
Client::Client():
authUser(0, ""),
updateAvailable(false)
@ -117,6 +123,95 @@ Client::Client():
versionCheckRequest = http_async_req_start(NULL, SERVER "/Download/Version.json", NULL, 0, 1);
}
std::vector<std::string> Client::DirectorySearch(std::string directory, std::string search, std::string extension)
{
std::vector<std::string> extensions;
extensions.push_back(extension);
return DirectorySearch(directory, search, extensions);
}
std::vector<std::string> Client::DirectorySearch(std::string directory, std::string search, std::vector<std::string> extensions)
{
std::vector<std::string> results;
//Get full file listing
std::vector<std::string> directoryList;
#if defined(WIN32) && !defined(__GNUC__)
//Windows
struct _finddata_t currentFile;
intptr_t findFileHandle;
std::string fileMatch = directory + "*.*";
findFileHandle = _findfirst(fileMatch.c_str(), &currentFile);
if (findFileHandle == -1L)
{
printf("Unable to open directory\n");
return std::vector<std::string>();
}
do
{
std::string currentFileName = std::string(currentFile.name);
if(currentFileName.length()>4)
directoryList.push_back(directory+currentFileName);
}
while (_findnext(findFileHandle, &currentFile) == 0);
_findclose(findFileHandle);
#else
//Linux or MinGW
struct dirent * directoryEntry;
DIR *directoryHandle = opendir(directory.c_str());
if(!directoryHandle)
{
printf("Unable to open directory\n");
return std::vector<std::string>();
}
while(directoryEntry = readdir(directoryHandle))
{
std::string currentFileName = std::string(directoryEntry->d_name);
if(currentFileName.length()>4)
directoryList.push_back(directory+currentFileName);
}
closedir(directoryHandle);
#endif
//Filter results
return directoryList;
return results;
}
std::vector<unsigned char> Client::ReadFile(std::string filename)
{
try
{
std::ifstream fileStream;
fileStream.open(string(filename).c_str(), ios::binary);
if(fileStream.is_open())
{
fileStream.seekg(0, ios::end);
size_t fileSize = fileStream.tellg();
fileStream.seekg(0);
unsigned char * tempData = new unsigned char[fileSize];
fileStream.read((char *)tempData, fileSize);
fileStream.close();
std::vector<unsigned char> fileData;
fileData.insert(fileData.end(), tempData, tempData+fileSize);
delete[] tempData;
return fileData;
}
else
{
return std::vector<unsigned char>();
}
}
catch(std::exception & e)
{
std::cerr << "Readfile: " << e.what() << std::endl;
throw;
}
}
void Client::Tick()
{
//Check status on version check request

View File

@ -81,6 +81,11 @@ public:
Client();
~Client();
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::vector<std::string> extensions);
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::string extension);
std::vector<unsigned char> ReadFile(std::string filename);
void AddListener(ClientListener * listener);
void RemoveListener(ClientListener * listener);

View File

@ -7,6 +7,7 @@
//
#include <iostream>
#include <sstream>
#include <bzlib.h>
#include "Config.h"
#include "bson/BSON.h"
@ -56,6 +57,50 @@ GameSave::GameSave(int width, int height)
setSize(width, height);
}
GameSave::GameSave(std::vector<char> data)
{
blockWidth = 0;
blockHeight = 0;
blockMap = NULL;
blockMapPtr = NULL;
fanVelX = NULL;
fanVelXPtr = NULL;
fanVelY = NULL;
fanVelYPtr = NULL;
particles = NULL;
try{
read(&data[0], data.size());
} catch (ParseException& e) {
std::cout << e.what() << std::endl;
this->~GameSave(); //Free any allocated memory
throw;
}
}
GameSave::GameSave(std::vector<unsigned char> data)
{
blockWidth = 0;
blockHeight = 0;
blockMap = NULL;
blockMapPtr = NULL;
fanVelX = NULL;
fanVelXPtr = NULL;
fanVelY = NULL;
fanVelYPtr = NULL;
particles = NULL;
try{
read((char*)(&data[0]), data.size());
} catch (ParseException& e) {
std::cout << e.what() << std::endl;
this->~GameSave(); //Free any allocated memory
throw;
}
}
GameSave::GameSave(char * data, int dataSize)
{
blockWidth = 0;
@ -69,27 +114,8 @@ GameSave::GameSave(char * data, int dataSize)
fanVelYPtr = NULL;
particles = NULL;
try {
if(dataSize > 0)
{
if(data[0] == 0x50 || data[0] == 0x66)
{
readPSv(data, dataSize);
}
else if(data[0] == 'O')
{
readOPS(data, dataSize);
}
else
{
std::cerr << "Got Magic number '" << data[0] << "'" << std::endl;
throw ParseException(ParseException::Corrupt, "Invalid save format");
}
}
else
{
throw ParseException(ParseException::Corrupt, "No data");
}
try{
read(data, dataSize);
} catch (ParseException& e) {
std::cout << e.what() << std::endl;
this->~GameSave(); //Free any allocated memory
@ -97,6 +123,30 @@ GameSave::GameSave(char * data, int dataSize)
}
}
void GameSave::read(char * data, int dataSize)
{
if(dataSize > 0)
{
if(data[0] == 0x50 || data[0] == 0x66)
{
readPSv(data, dataSize);
}
else if(data[0] == 'O')
{
readOPS(data, dataSize);
}
else
{
std::cerr << "Got Magic number '" << data[0] << "'" << std::endl;
throw ParseException(ParseException::Corrupt, "Invalid save format");
}
}
else
{
throw ParseException(ParseException::Corrupt, "No data");
}
}
void GameSave::setSize(int newWidth, int newHeight)
{
this->blockWidth = newWidth;
@ -895,8 +945,13 @@ void GameSave::readPSv(char * data, int dataLength)
setSize(bw, bh);
if (BZ2_bzBuffToBuffDecompress((char *)d, (unsigned *)&i, (char *)(c+12), dataLength-12, 0, 0))
throw ParseException(ParseException::Corrupt, "Cannot decompress");
int bzStatus = 0;
if (bzStatus = BZ2_bzBuffToBuffDecompress((char *)d, (unsigned *)&i, (char *)(c+12), dataLength-12, 0, 0))
{
std::stringstream bzStatusStr;
bzStatusStr << bzStatus;
throw ParseException(ParseException::Corrupt, "Cannot decompress: " + bzStatusStr.str());
}
dataLength = i;
std::cout << "Parsing " << dataLength << " bytes of data, version " << ver << std::endl;

View File

@ -59,6 +59,8 @@ public:
GameSave(GameSave & save);
GameSave(int width, int height);
GameSave(char * data, int dataSize);
GameSave(std::vector<char> data);
GameSave(std::vector<unsigned char> data);
~GameSave();
void setSize(int width, int height);
char * Serialise(int & dataSize);
@ -85,6 +87,7 @@ private:
float * fanVelYPtr;
unsigned char * blockMapPtr;
void read(char * data, int dataSize);
void readOPS(char * data, int dataLength);
void readPSv(char * data, int dataLength);
char * serialiseOPS(int & dataSize);

View File

@ -6,19 +6,35 @@
*/
#include "SaveFile.h"
#include "Client.h"
#include "search/Thumbnail.h"
SaveFile::SaveFile(SaveFile & save):
gameSave(NULL)
gameSave(NULL),
thumbnail(NULL)
{
if(save.gameSave)
gameSave = new GameSave(*save.gameSave);
if(save.thumbnail)
thumbnail = new Thumbnail(*save.thumbnail);
}
Thumbnail * SaveFile::GetThumbnail()
{
return thumbnail;
}
void SaveFile::SetThumbnail(Thumbnail * thumb)
{
thumbnail = thumb;
}
SaveFile::SaveFile(string filename):
filename(filename),
gameSave(NULL)
{
//Load file
gameSave(NULL),
thumbnail(NULL)
{
}
GameSave * SaveFile::GetGameSave()
@ -39,5 +55,7 @@ string SaveFile::GetName()
SaveFile::~SaveFile() {
if(gameSave)
delete gameSave;
if(thumbnail)
delete thumbnail;
}

View File

@ -11,19 +11,24 @@
#include <string>
#include "GameSave.h"
using namespace std;
class Thumbnail;
class SaveFile {
public:
SaveFile(SaveFile & save);
SaveFile(string filename);
Thumbnail * GetThumbnail();
GameSave * GetGameSave();
void SetThumbnail(Thumbnail * thumb);
void SetGameSave(GameSave * save);
string GetName();
virtual ~SaveFile();
private:
Thumbnail * thumbnail;
GameSave * gameSave;
string filename;
};

View File

@ -0,0 +1,238 @@
#include <sstream>
#include <iostream>
#include "FileBrowserActivity.h"
#include "interface/Label.h"
#include "interface/Textbox.h"
#include "interface/ScrollPanel.h"
#include "interface/SaveButton.h"
#include "interface/ProgressBar.h"
#include "client/Client.h"
#include "client/SaveFile.h"
#include "Style.h"
#include "tasks/Task.h"
#include "simulation/SaveRenderer.h"
class Thumbnail;
class SaveSelectedAction: public ui::SaveButtonAction
{
FileBrowserActivity * a;
public:
SaveSelectedAction(FileBrowserActivity * _a) { a = _a; }
virtual void ActionCallback(ui::SaveButton * sender)
{
a->SelectSave(sender->GetSaveFile());
}
};
//Currently, reading is done on another thread, we can't render outside the main thread due to some bullshit with OpenGL
class LoadFilesTask: public Task
{
std::string directory;
std::vector<SaveFile*> saveFiles;
virtual void before()
{
}
virtual void after()
{
}
virtual bool doWork()
{
std::vector<std::string> files = Client::Ref().DirectorySearch(directory, "", ".cps");
notifyProgress(-1);
for(std::vector<std::string>::iterator iter = files.begin(), end = files.end(); iter != end; ++iter)
{
SaveFile * saveFile = new SaveFile(*iter);
try
{
std::vector<unsigned char> data = Client::Ref().ReadFile(*iter);
GameSave * tempSave = new GameSave(data);
saveFile->SetGameSave(tempSave);
saveFiles.push_back(saveFile);
}
catch(std::exception & e)
{
//:(
}
}
return true;
}
public:
std::vector<SaveFile*> GetSaveFiles()
{
return saveFiles;
}
LoadFilesTask(std::string directory):
directory(directory)
{
}
};
FileBrowserActivity::FileBrowserActivity(std::string directory, FileSelectedCallback * callback):
ui::Window(ui::Point(-1, -1), ui::Point(450, 300)),
callback(callback),
directory(directory),
totalFiles(0)
{
ui::Engine::Ref().ShowWindow(this);
ui::Label * titleLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 18), "Save Browser");
titleLabel->SetTextColour(style::Colour::WarningTitle);
titleLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
AddComponent(titleLabel);
//ui::Textbox * textField = new ui::Textbox(ui::Point(8, 25), ui::Point(Size.X-16, 16), "", "[search]");
//textField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
//textField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
//AddComponent(textField);
itemList = new ui::ScrollPanel(ui::Point(4, 45), ui::Point(Size.X-8, Size.Y-53));
AddComponent(itemList);
progressBar = new ui::ProgressBar(ui::Point((Size.X-200)/2, 45+(Size.Y-66)/2), ui::Point(200, 17));
AddComponent(progressBar);
filesX = 4;
filesY = 3;
buttonPadding = 2;
fileX = 0;
fileY = 0;
buttonXOffset = 0;
buttonYOffset = 0;
buttonAreaWidth = itemList->Size.X;
buttonAreaHeight = itemList->Size.Y;// - buttonYOffset - 18;
buttonWidth = (buttonAreaWidth/filesX) - buttonPadding*2;
buttonHeight = (buttonAreaHeight/filesY) - buttonPadding*2;
loadDirectory(directory);
}
void FileBrowserActivity::SelectSave(SaveFile * file)
{
if(callback)
callback->FileSelected(new SaveFile(*file));
Exit();
}
void FileBrowserActivity::loadDirectory(std::string directory)
{
progressBar->Visible = true;
progressBar->SetProgress(-1);
progressBar->SetStatus("Loading files");
loadFiles = new LoadFilesTask(directory);
loadFiles->AddTaskListener(this);
loadFiles->Start();
}
void FileBrowserActivity::NotifyDone(Task * task)
{
for(int i = 0; i < components.size(); i++)
{
RemoveComponent(components[i]);
itemList->RemoveChild(components[i]);
delete components[i];
}
fileX = 0;
fileY = 0;
files = ((LoadFilesTask*)task)->GetSaveFiles();
totalFiles = files.size();
delete task;
loadFiles = NULL;
}
void FileBrowserActivity::OnMouseDown(int x, int y, unsigned button)
{
if(!(x > Position.X && y > Position.Y && y < Position.Y+Size.Y && x < Position.X+Size.X)) //Clicked outside window
Exit();
}
void FileBrowserActivity::Exit()
{
ui::Engine::Ref().CloseWindow();
SelfDestruct();
}
void FileBrowserActivity::NotifyError(Task * task)
{
}
void FileBrowserActivity::NotifyProgress(Task * task)
{
progressBar->SetProgress(task->GetProgress());
}
void FileBrowserActivity::NotifyStatus(Task * task)
{
}
void FileBrowserActivity::OnTick(float dt)
{
if(loadFiles)
loadFiles->Poll();
if(files.size())
{
SaveFile * saveFile = files.back();
files.pop_back();
if(fileX == filesX)
{
fileX = 0;
fileY++;
}
ui::SaveButton * saveButton = new ui::SaveButton(
ui::Point(
buttonXOffset + buttonPadding + fileX*(buttonWidth+buttonPadding*2),
buttonYOffset + buttonPadding + fileY*(buttonHeight+buttonPadding*2)
),
ui::Point(buttonWidth, buttonHeight),
saveFile);
saveButton->Tick(dt);
saveButton->SetActionCallback(new SaveSelectedAction(this));
progressBar->SetStatus("Rendering thumbnails");
progressBar->SetProgress((float(totalFiles-files.size())/float(totalFiles))*100.0f);
componentsQueue.push_back(saveButton);
fileX++;
}
else if(componentsQueue.size())
{
for(std::vector<ui::Component*>::iterator iter = componentsQueue.begin(), end = componentsQueue.end(); iter != end; ++iter)
{
components.push_back(*iter);
itemList->AddChild(*iter);
}
componentsQueue.clear();
itemList->InnerSize.Y = (buttonHeight+(buttonPadding*2))*fileY;
progressBar->Visible = false;
}
}
void FileBrowserActivity::OnDraw()
{
Graphics * g = ui::Engine::Ref().g;
//Window Background+Outline
g->clearrect(Position.X-2, Position.Y-2, Size.X+4, Size.Y+4);
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255);
}
FileBrowserActivity::~FileBrowserActivity()
{
if(callback)
delete callback;
}

View File

@ -0,0 +1,58 @@
#pragma once
#include <vector>
#include <string>
#include "interface/Window.h"
#include "tasks/TaskListener.h"
class SaveFile;
class FileSelectedCallback
{
public:
FileSelectedCallback() {}
virtual ~FileSelectedCallback() {}
virtual void FileSelected(SaveFile* file) {}
};
namespace ui
{
class ScrollPanel;
class ProgressBar;
}
class LoadFilesTask;
class FileBrowserActivity: public ui::Window, public TaskListener
{
LoadFilesTask * loadFiles;
FileSelectedCallback * callback;
ui::ScrollPanel * itemList;
std::vector<SaveFile*> files;
std::vector<ui::Component*> components;
std::vector<ui::Component*> componentsQueue;
std::string directory;
ui::ProgressBar * progressBar;
int totalFiles;
int filesX, filesY, buttonPadding;
int fileX, fileY;
int buttonWidth, buttonHeight, buttonAreaWidth, buttonAreaHeight, buttonXOffset, buttonYOffset;
void populateList();
public:
FileBrowserActivity(std::string directory, FileSelectedCallback * callback);
virtual void OnDraw();
virtual void OnTick(float dt);
virtual void OnMouseDown(int x, int y, unsigned button);
void loadDirectory(std::string directory);
void SelectSave(SaveFile * file);
virtual ~FileBrowserActivity();
virtual void NotifyDone(Task * task);
virtual void NotifyError(Task * task);
virtual void NotifyProgress(Task * task);
virtual void NotifyStatus(Task * task);
void Exit();
};

View File

@ -16,6 +16,7 @@
#include "elementsearch/ElementSearchActivity.h"
#include "update/UpdateActivity.h"
#include "Notification.h"
#include "filebrowser/FileBrowserActivity.h"
using namespace std;
@ -523,6 +524,32 @@ void GameController::OpenSearch()
ui::Engine::Ref().ShowWindow(search->GetView());
}
void GameController::OpenLocalSaveWindow()
{
}
void GameController::LoadSaveFile(SaveFile * file)
{
gameModel->SetSaveFile(file);
}
void GameController::OpenLocalBrowse()
{
class LocalSaveOpenCallback: public FileSelectedCallback
{
GameController * c;
public:
LocalSaveOpenCallback(GameController * _c): c(_c) {}
virtual ~LocalSaveOpenCallback() {};
virtual void FileSelected(SaveFile* file)
{
c->LoadSaveFile(file);
}
};
new FileBrowserActivity(LOCAL_SAVE_DIR PATH_SEP, new LocalSaveOpenCallback(this));
}
void GameController::OpenLogin()
{
loginWindow = new LoginController(new LoginCallback(this));

View File

@ -86,9 +86,12 @@ public:
void SetActiveTool(int toolSelection, Tool * tool);
void SetColour(ui::Colour colour);
void SetToolStrength(float value);
void LoadSaveFile(SaveFile * file);
void OpenSearch();
void OpenLogin();
void OpenTags();
void OpenLocalSaveWindow();
void OpenLocalBrowse();
void OpenOptions();
void OpenRenderOptions();
void OpenSaveWindow();

View File

@ -308,6 +308,34 @@ void GameModel::SetSave(SaveInfo * newSave)
notifySaveChanged();
}
void GameModel::SetSaveFile(SaveFile * newSave)
{
SetSave(NULL);
if(newSave && newSave->GetGameSave())
{
GameSave * saveData = newSave->GetGameSave();
SetPaused(saveData->paused & GetPaused());
sim->gravityMode = saveData->gravityMode;
sim->air->airMode = saveData->airMode;
sim->legacy_enable = saveData->legacyEnable;
sim->water_equal_test = saveData->waterEEnabled;
if(saveData->gravityEnable && !sim->grav->ngrav_enable)
{
sim->grav->start_grav_async();
}
else if(!saveData->gravityEnable && sim->grav->ngrav_enable)
{
sim->grav->stop_grav_async();
}
sim->clear_sim();
sim->Load(saveData);
}
delete newSave;
notifySaveChanged();
}
Simulation * GameModel::GetSimulation()
{
return sim;

View File

@ -95,6 +95,7 @@ public:
SaveInfo * GetSave();
Brush * GetBrush();
void SetSave(SaveInfo * newSave);
void SetSaveFile(SaveFile * newSave);
void AddObserver(GameView * observer);
Tool * GetActiveTool(int selection);
void SetActiveTool(int selection, Tool * tool);

View File

@ -37,7 +37,8 @@ GameView::GameView():
toolTip(""),
infoTip(""),
infoTipPresence(0),
toolTipPosition(-1, -1)
toolTipPosition(-1, -1),
alternativeSaveSource(false)
{
int currentX = 1;
@ -49,7 +50,10 @@ GameView::GameView():
SearchAction(GameView * _v) { v = _v; }
void ActionCallback(ui::Button * sender)
{
v->c->OpenSearch();
if(v->GetAlternativeSourceEnabled())
v->c->OpenLocalBrowse();
else
v->c->OpenSearch();
}
};
@ -89,7 +93,10 @@ GameView::GameView():
SaveSimulationAction(GameView * _v) { v = _v; }
void ActionCallback(ui::Button * sender)
{
v->c->OpenSaveWindow();
if(v->GetAlternativeSourceEnabled())
v->c->OpenLocalSaveWindow();
else
v->c->OpenSaveWindow();
}
};
saveSimulationButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(150, 15), "[untitled simulation]");
@ -847,6 +854,7 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool
drawMode = DrawFill;
else
drawMode = DrawRect;
enableHDDSave();
break;
case KEY_SHIFT:
if(drawModeReset)
@ -940,6 +948,9 @@ void GameView::OnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bo
case KEY_ALT:
drawSnap = false;
break;
case KEY_CTRL:
disableHDDSave();
break;
case 'z':
if(!zoomCursorFixed)
c->SetZoomEnabled(false);
@ -1152,6 +1163,32 @@ void GameView::changeColour()
c->SetColour(ui::Colour(colourRSlider->GetValue(), colourGSlider->GetValue(), colourBSlider->GetValue(), colourASlider->GetValue()));
}
void GameView::enableHDDSave()
{
if(!alternativeSaveSource)
{
alternativeSaveSource = true;
saveSimulationButton->Appearance.BackgroundInactive = ui::Colour(255, 255, 255);
saveSimulationButton->Appearance.TextInactive = ui::Colour(0, 0, 0);
searchButton->Appearance.BackgroundInactive = ui::Colour(255, 255, 255);
searchButton->Appearance.TextInactive = ui::Colour(0, 0, 0);
}
}
void GameView::disableHDDSave()
{
if(alternativeSaveSource)
{
alternativeSaveSource = false;
saveSimulationButton->Appearance.BackgroundInactive = ui::Colour(0, 0, 0);
saveSimulationButton->Appearance.TextInactive = ui::Colour(255, 255, 255);
searchButton->Appearance.BackgroundInactive = ui::Colour(0, 0, 0);
searchButton->Appearance.TextInactive = ui::Colour(255, 255, 255);
}
}
void GameView::OnDraw()
{
Graphics * g = ui::Engine::Ref().g;

View File

@ -37,6 +37,7 @@ private:
bool zoomEnabled;
bool zoomCursorFixed;
bool drawSnap;
bool alternativeSaveSource;
int toolIndex;
int infoTipPresence;
@ -94,12 +95,16 @@ private:
void changeColour();
virtual ui::Point lineSnapCoords(ui::Point point1, ui::Point point2);
virtual ui::Point rectSnapCoords(ui::Point point1, ui::Point point2);
void enableHDDSave();
void disableHDDSave();
public:
GameView();
//Breaks MVC, but any other way is going to be more of a mess.
ui::Point GetMousePosition();
void SetSample(SimulationSample sample);
bool GetAlternativeSourceEnabled(){ return alternativeSaveSource; }
void AttachController(GameController * _c){ c = _c; }
void NotifyRendererChanged(GameModel * sender);

View File

@ -31,7 +31,6 @@ VideoBuffer::VideoBuffer(VideoBuffer * old):
std::copy(old->Buffer, old->Buffer+(old->Width*old->Height), Buffer);
};
VideoBuffer::~VideoBuffer()
{
delete[] Buffer;

View File

@ -135,6 +135,9 @@ public:
static int textwidth(const char *s);
static void textsize(const char * s, int & width, int & height);
void Acquire();
void Release();
void blendpixel(int x, int y, int r, int g, int b, int a);
void addpixel(int x, int y, int r, int g, int b, int a);

View File

@ -1,11 +1,17 @@
#include "Graphics.h"
#include "font.h"
#include <pthread.h>
#ifdef OGLI
static pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER;
Graphics::Graphics():
sdl_scale(1)
{
if(gMutex == PTHREAD_MUTEX_INITIALIZER)
pthread_mutex_init (&gMutex, NULL);
Reset();
glEnable(GL_BLEND);
@ -35,6 +41,16 @@ sdl_scale(1)
glDisable(GL_TEXTURE_2D);
}
void Graphics::Acquire()
{
pthread_mutex_lock(&gMutex);
}
void Graphics::Release()
{
pthread_mutex_unlock(&gMutex);
}
Graphics::~Graphics()
{
}

View File

@ -329,7 +329,7 @@ void PIXELMETHODS_CLASS::clearrect(int x, int y, int w, int h)
void PIXELMETHODS_CLASS::draw_image(pixel *img, int x, int y, int w, int h, int a)
{
int i, j, r, g, b;
if (!img) return;
if (!img || y >= VIDYRES) return;
if(y + h > VIDYRES) h = (VIDYRES)-y; //Adjust height to prevent drawing off the bottom
if(a >= 255)
for (j=0; j<h; j++)

View File

@ -9,6 +9,16 @@ sdl_scale(1)
}
void Graphics::Acquire()
{
}
void Graphics::Release()
{
}
Graphics::~Graphics()
{
free(vid);

View File

@ -85,16 +85,19 @@ void Button::Draw(const Point& screenPos)
}
Graphics * g = ui::Engine::Ref().g;
Point Position = screenPos;
ui::Colour bgColour(0, 0, 0);
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);
}
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);
@ -102,23 +105,27 @@ void Button::Draw(const Point& screenPos)
}
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);
}
bool iconInvert = (bgColour.Blue + (3*bgColour.Green) + (2*bgColour.Red))>544?true:false;
if(Appearance.icon)
{
if(Enabled)
if(isButtonDown || (isTogglable && toggle))
{
g->draw_icon(Position.X+iconPosition.X, Position.Y+iconPosition.Y, Appearance.icon, 255, true);
g->draw_icon(Position.X+iconPosition.X, Position.Y+iconPosition.Y, Appearance.icon, 255, iconInvert);
}
else
{
g->draw_icon(Position.X+iconPosition.X, Position.Y+iconPosition.Y, Appearance.icon, 255);
g->draw_icon(Position.X+iconPosition.X, Position.Y+iconPosition.Y, Appearance.icon, 255, iconInvert);
}
else
g->draw_icon(Position.X+iconPosition.X, Position.Y+iconPosition.Y, Appearance.icon, 180);
g->draw_icon(Position.X+iconPosition.X, Position.Y+iconPosition.Y, Appearance.icon, 180, iconInvert);
}
}

View File

@ -170,6 +170,7 @@ void Engine::Draw()
{
if(lastBuffer && !(state_->Position.X == 0 && state_->Position.Y == 0 && state_->Size.X == width_ && state_->Size.Y == height_))
{
g->Acquire();
g->Clear();
#ifndef OGLI
memcpy(g->vid, lastBuffer, (width_ * height_) * PIXELSIZE);
@ -188,6 +189,7 @@ void Engine::Draw()
ui::Engine::Ref().g->drawtext(10, 10, fpsText, 255, 255, 255, 255);
#endif
g->Finalise();
g->Release();
FrameIndex++;
FrameIndex %= 7200;
}

View File

@ -161,7 +161,7 @@ void Panel::Draw(const Point& screenPos)
//dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x;
for (int row = 0; row < Size.Y; row++)
{
std::copy(myVid+(row*Size.W), myVid+(row*Size.W)+Size.W, lastVid+(screenPos.Y*(XRES+BARSIZE))+screenPos.X);
std::copy(myVid+(row*(XRES+BARSIZE)), myVid+(row*(XRES+BARSIZE))+Size.X, lastVid+((screenPos.Y+row)*(XRES+BARSIZE))+screenPos.X);
}
#endif
}

View File

@ -0,0 +1,65 @@
#include "ProgressBar.h"
#include "Style.h"
using namespace ui;
ProgressBar::ProgressBar(Point position, Point size):
Component(position, size),
intermediatePos(0.0f),
progressStatus("")
{
progress = 0;
}
void ProgressBar::SetProgress(int progress)
{
this->progress = progress;
}
void ProgressBar::SetStatus(std::string status)
{
progressStatus = status;
}
void ProgressBar::Draw(const Point & screenPos)
{
Graphics * g = ui::Engine::Ref().g;
ui::Colour progressBarColour = style::Colour::WarningTitle;
g->drawrect(screenPos.X, screenPos.Y, Size.X, Size.Y, 255, 255, 255, 255);
if(progress!=-1)
{
if(progress > 0)
{
float size = float(Size.X-4)*(float(progress)/100.0f); // TIL...
size = std::min(std::max(size, 0.0f), float(Size.X-4));
g->fillrect(screenPos.X + 2, screenPos.Y + 2, size, Size.Y-4, progressBarColour.Red, progressBarColour.Green, progressBarColour.Blue, 255);
}
} else {
int size = 40, rsize = 0;
float position = float(Size.X-4)*(intermediatePos/100.0f);
if(position + size - 1 > Size.X-4)
{
size = (Size.X-4)-position+1;
rsize = 40-size;
}
g->fillrect(screenPos.X + 2 + position, screenPos.Y + 2, size, Size.Y-4, progressBarColour.Red, progressBarColour.Green, progressBarColour.Blue, 255);
if(rsize)
{
g->fillrect(screenPos.X + 2, screenPos.Y + 2, rsize, Size.Y-4, progressBarColour.Red, progressBarColour.Green, progressBarColour.Blue, 255);
}
}
if(progress<50)
g->drawtext(screenPos.X + ((Size.X-Graphics::textwidth(progressStatus.c_str()))/2), screenPos.Y + (Size.Y-8)/2, progressStatus, 255, 255, 255, 255);
else
g->drawtext(screenPos.X + ((Size.X-Graphics::textwidth(progressStatus.c_str()))/2), screenPos.Y + (Size.Y-8)/2, progressStatus, 0, 0, 0, 255);
}
void ProgressBar::Tick(float dt)
{
intermediatePos += 1.0f*dt;
if(intermediatePos>100.0f)
intermediatePos = 0.0f;
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "Component.h"
namespace ui
{
class ProgressBar: public Component
{
int progress;
float intermediatePos;
std::string progressStatus;
public:
ProgressBar(Point position, Point size);
virtual void SetProgress(int progress);
virtual void SetStatus(std::string status);
virtual void Draw(const Point & screenPos);
virtual void Tick(float dt);
};
}

View File

@ -61,7 +61,8 @@ SaveButton::SaveButton(Point position, Point size, SaveFile * file):
actionCallback(NULL),
voteColour(255, 0, 0),
selectable(false),
selected(false)
selected(false),
wantsDraw(false)
{
if(file)
{
@ -91,7 +92,7 @@ void SaveButton::Tick(float dt)
{
Thumbnail * tempThumb;
float scaleFactorY = 1.0f, scaleFactorX = 1.0f;
if(!thumbnail)
if(!thumbnail/* && wantsDraw*/)
{
if(save)
{
@ -114,7 +115,11 @@ void SaveButton::Tick(float dt)
}
if(file)
{
if(file->GetGameSave())
if(file->GetThumbnail())
{
thumbnail = new Thumbnail(*file->GetThumbnail());
}
else if(file->GetGameSave())
{
thumbnail = SaveRenderer::Ref().Render(file->GetGameSave());
}
@ -152,6 +157,8 @@ void SaveButton::Draw(const Point& screenPos)
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);

View File

@ -27,6 +27,7 @@ class SaveButton : public Component
SaveInfo * save;
Thumbnail * thumbnail;
std::string name;
bool wantsDraw;
public:
SaveButton(Point position, Point size, SaveInfo * save);
SaveButton(Point position, Point size, SaveFile * file);

View File

@ -28,7 +28,7 @@ void ScrollPanel::XOnMouseWheelInside(int localx, int localy, int d)
{
if(!d)
return;
yScrollVel -= d;
yScrollVel -= d*2;
}
void ScrollPanel::XDraw(const Point& screenPos)
@ -52,8 +52,8 @@ void ScrollPanel::XDraw(const Point& screenPos)
void ScrollPanel::XTick(float dt)
{
if(yScrollVel > 7.0f) yScrollVel = 7.0f;
if(yScrollVel < -7.0f) yScrollVel = -7.0f;
//if(yScrollVel > 7.0f) yScrollVel = 7.0f;
//if(yScrollVel < -7.0f) yScrollVel = -7.0f;
if(yScrollVel > -0.5f && yScrollVel < 0.5)
yScrollVel = 0;
@ -63,14 +63,16 @@ void ScrollPanel::XTick(float dt)
xScrollVel = 0;
maxOffset = InnerSize-Size;
maxOffset.Y = std::max(0, maxOffset.Y);
maxOffset.X = std::max(0, maxOffset.X);
int oldOffsetY = offsetY;
offsetY += yScrollVel;
int oldOffsetX = offsetX;
offsetX += xScrollVel;
yScrollVel*=0.99f;
xScrollVel*=0.99f;
yScrollVel*=0.98f;
xScrollVel*=0.98f;
if(oldOffsetY!=int(offsetY))
{

View File

@ -42,6 +42,7 @@ Thumbnail * SaveRenderer::Render(GameSave * save)
width = save->blockWidth;
height = save->blockHeight;
g->Acquire();
g->Clear();
sim->clear_sim();
@ -69,7 +70,7 @@ Thumbnail * SaveRenderer::Render(GameSave * save)
pData = new pixel[XRES*YRES];
texData = new unsigned char[(XRES*YRES)*PIXELSIZE];
std::fill(texData, texData+(XRES*YRES), 0xDD);
std::fill(texData, texData+(XRES*YRES)*PIXELSIZE, 0xDD);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
glDisable(GL_TEXTURE_2D);
@ -111,6 +112,7 @@ Thumbnail * SaveRenderer::Render(GameSave * save)
free(pData);
#endif
}
g->Release();
return tempThumb;
}

View File

@ -23,7 +23,7 @@ public:
std::string GetError();
std::string GetStatus();
void Poll();
Task() {}
Task() { progress = 0; }
virtual ~Task();
protected:
int progress;