Merge pull request #1424 from ThomasdenH/load_save_sorting

Load save sorting by date
This commit is contained in:
Ted John 2015-06-22 16:00:41 +01:00
commit 473eea3bfc
7 changed files with 190 additions and 50 deletions

View File

@ -3705,4 +3705,8 @@ STR_5368 :Reset crash status
STR_5369 :Park parameters...
STR_5370 :{SMALLFONT}{BLACK}Click this button to modify park{NEWLINE}parameters like restrictions,{NEWLINE}guest generation and money.
STR_5371 :Object Selection
STR_5372 :Invert right mouse dragging
STR_5372 :Invert right mouse dragging
STR_5373 :Name {STRINGID}
STR_5374 :Date {STRINGID}
STR_5375 :{UP}
STR_5376 :{DOWN}

View File

@ -181,6 +181,7 @@ config_property_definition _generalDefinitions[] = {
{ offsetof(general_configuration, last_run_version), "last_run_version", CONFIG_VALUE_TYPE_STRING, { .value_string = NULL }, NULL },
{ offsetof(general_configuration, title_sequence), "title_sequence", CONFIG_VALUE_TYPE_UINT8, TITLE_SEQUENCE_OPENRCT2, NULL },
{ offsetof(general_configuration, invert_viewport_drag), "invert_viewport_drag", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
{ offsetof(general_configuration, load_save_sort), "load_save_sort", CONFIG_VALUE_TYPE_UINT8, SORT_NAME_ASCENDING, NULL },
};
config_property_definition _interfaceDefinitions[] = {

View File

@ -112,6 +112,13 @@ enum {
TITLE_SEQUENCE_RANDOM
};
enum {
SORT_NAME_ASCENDING,
SORT_NAME_DESCENDING,
SORT_DATE_ASCENDING,
SORT_DATE_DESCENDING,
};
typedef struct {
uint8 play_intro;
uint8 confirmation_prompt;
@ -145,6 +152,7 @@ typedef struct {
utf8string last_run_version;
uint8 title_sequence;
uint8 invert_viewport_drag;
uint8 load_save_sort;
} general_configuration;
typedef struct {

View File

@ -1545,6 +1545,11 @@ enum {
STR_INVERT_RIGHT_MOUSE_DRAG = 5372,
STR_NAME = 5373,
STR_DATE = 5374,
STR_UP = 5375,
STR_DOWN = 5376,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
STR_COUNT = 32768
};

View File

@ -87,6 +87,7 @@ void platform_stop_text_input();
char platform_get_path_separator();
int platform_file_exists(const char *path);
int platform_directory_exists(const char *path);
time_t platform_file_get_modified_time(char* path);
int platform_ensure_directory_exists(const char *path);
int platform_lock_single_instance();
int platform_enumerate_files_begin(const char *pattern);
@ -95,6 +96,10 @@ void platform_enumerate_files_end(int handle);
int platform_enumerate_directories_begin(const char *directory);
int platform_enumerate_directories_next(int handle, char *path);
void platform_enumerate_directories_end(int handle);
// Returns the bitmask of the GetLogicalDrives function for windows, 0 for other systems
int platform_get_drives();
int platform_file_copy(const char *srcPath, const char *dstPath);
int platform_file_move(const char *srcPath, const char *dstPath);
int platform_file_delete(const char *path);

View File

@ -23,6 +23,7 @@
#include <windows.h>
#include <shlobj.h>
#include <SDL_syswm.h>
#include <sys/stat.h>
#include "../addresses.h"
#include "../cmdline.h"
#include "../openrct2.h"
@ -265,6 +266,10 @@ void platform_enumerate_directories_end(int handle)
enumFileInfo->active = 0;
}
int platform_get_drives(){
return GetLogicalDrives();
}
int platform_file_copy(const char *srcPath, const char *dstPath)
{
return CopyFileA(srcPath, dstPath, TRUE);
@ -641,6 +646,12 @@ uint16 platform_get_locale_language(){
return LANGUAGE_UNDEFINED;
}
time_t platform_file_get_modified_time(char* path){
struct _stat stat;
_stat(path, &stat);
return stat.st_mtime;
}
uint8 platform_get_locale_currency(){
CHAR currCode[4];

View File

@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <time.h>
#include "../addresses.h"
#include "../config.h"
#include "../game.h"
@ -40,17 +41,21 @@ enum {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_SORT_NAME,
WIDX_SORT_DATE,
WIDX_SCROLL,
WIDX_BROWSE,
};
// 0x9DE48C
static rct_widget window_loadsave_widgets[] = {
{ WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, STR_NONE, STR_NONE },
{ WWT_CAPTION, 0, 1, WW - 2, 1, 14, STR_NONE, STR_WINDOW_TITLE_TIP },
{ WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
{ WWT_SCROLL, 0, 4, WW - 5, 36, WH - 40, 2, STR_NONE },
{ WWT_CLOSEBOX, 0, 4, 200, WH - 36, WH - 18, 2707, STR_NONE }, // Use native browser
{ WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, STR_NONE, STR_NONE },
{ WWT_CAPTION, 0, 1, WW - 2, 1, 14, STR_NONE, STR_WINDOW_TITLE_TIP },
{ WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
{ WWT_CLOSEBOX, 0, 4, (WW - 5) / 2, 36, 47, STR_NONE, STR_NONE },
{ WWT_CLOSEBOX, 0, (WW - 5) / 2 + 1, WW - 5 - 1, 36, 47, STR_NONE, STR_NONE },
{ WWT_SCROLL, 0, 4, WW - 5, 47, WH - 40, 2, STR_NONE },
{ WWT_CLOSEBOX, 0, 4, 200, WH - 36, WH - 18, 2707, STR_NONE }, // Use native browser
{ WIDGETS_END }
};
@ -104,9 +109,18 @@ static void* window_loadsave_events[] = {
#pragma endregion
enum {
TYPE_UP,
TYPE_NEW_FILE,
TYPE_DIRECTORY,
TYPE_FILE,
};
typedef struct {
char name[256];
char path[MAX_PATH];
time_t date_modified;
uint8 type;
} loadsave_list_item;
int _listItemsCount = 0;
@ -120,6 +134,7 @@ int _type;
static void window_loadsave_populate_list(int includeNewItem, bool browsable, const char *directory, const char *extension);
static void window_loadsave_select(rct_window *w, const char *path);
static void window_loadsave_sort_list(int index, int endIndex);
static int has_extension(char *path, char *extension);
@ -139,7 +154,7 @@ rct_window *window_loadsave_open(int type, char *defaultName)
if (w == NULL) {
w = window_create_centred(WW, WH, (uint32*)window_loadsave_events, WC_LOADSAVE, WF_STICK_TO_FRONT);
w->widgets = window_loadsave_widgets;
w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_BROWSE);
w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_SORT_NAME) | (1 << WIDX_SORT_DATE) | (1 << WIDX_BROWSE);
w->colours[0] = 7;
w->colours[1] = 7;
w->colours[2] = 7;
@ -296,6 +311,26 @@ static void window_loadsave_mouseup()
window_loadsave_select(w, filename);
}
break;
case WIDX_SORT_NAME:
if (gConfigGeneral.load_save_sort == SORT_NAME_ASCENDING){
gConfigGeneral.load_save_sort = SORT_NAME_DESCENDING;
} else {
gConfigGeneral.load_save_sort = SORT_NAME_ASCENDING;
}
config_save_default();
window_loadsave_sort_list(0, _listItemsCount - 1);
window_invalidate(w);
break;
case WIDX_SORT_DATE:
if (gConfigGeneral.load_save_sort == SORT_DATE_DESCENDING){
gConfigGeneral.load_save_sort = SORT_DATE_ASCENDING;
} else {
gConfigGeneral.load_save_sort = SORT_DATE_DESCENDING;
}
config_save_default();
window_loadsave_sort_list(0, _listItemsCount - 1);
window_invalidate(w);
break;
}
}
@ -335,8 +370,7 @@ static void window_loadsave_scrollmousedown()
if (selectedItem >= w->no_list_items)
return;
// Load or overwrite
if (_listItems[selectedItem].path[0] == 0) {
if (_listItems[selectedItem].type == TYPE_NEW_FILE) {
rct_string_id templateStringId = 3165;
char *templateString;
@ -345,7 +379,7 @@ static void window_loadsave_scrollmousedown()
window_text_input_open(w, WIDX_SCROLL, STR_NONE, 2710, templateStringId, 0, 64);
} else {
if (_listItems[selectedItem].path[strlen(_listItems[selectedItem].path) - 1] == platform_get_path_separator()){
if (_listItems[selectedItem].type == TYPE_DIRECTORY || _listItems[selectedItem].type == TYPE_UP){
// The selected item is a folder
int includeNewItem;
@ -362,6 +396,8 @@ static void window_loadsave_scrollmousedown()
w->no_list_items = _listItemsCount;
} else {
// TYPE_FILE
// Load or overwrite
if ((_loadsaveType & 1) == LOADSAVETYPE_SAVE)
window_overwrite_prompt_open(_listItems[selectedItem].name, _listItems[selectedItem].path);
else
@ -448,7 +484,19 @@ static void window_loadsave_paint()
sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, _shortenedDirectory);
// Draw shadow
gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 20);
rct_string_id id = STR_NONE;
if (gConfigGeneral.load_save_sort == SORT_NAME_ASCENDING)
id = STR_UP;
else if (gConfigGeneral.load_save_sort == SORT_NAME_DESCENDING)
id = STR_DOWN;
gfx_draw_string_centred_clipped(dpi, STR_NAME, &id, 1, w->x + 4 + (w->width - 8) / 4, w->y + 36, (w->width - 8) / 2);
if (gConfigGeneral.load_save_sort == SORT_DATE_ASCENDING)
id = STR_UP;
else if (gConfigGeneral.load_save_sort == SORT_DATE_DESCENDING)
id = STR_DOWN;
else
id = STR_NONE;
gfx_draw_string_centred_clipped(dpi, STR_DATE, &id, 1, w->x + 4 + (w->width - 8) * 3 / 4, w->y + 36, (w->width - 8) / 2);
}
static void shorten_path(char* path, char* buffer, int available_width){
@ -518,12 +566,35 @@ static void window_loadsave_scrollpaint()
}
}
static int compare_string_case_insensitive(char const *a, char const *b)
{
for (;; a++, b++) {
int d = tolower(*a) - tolower(*b);
if (d != 0 || !*a)
return d;
}
}
static int list_item_sort(const void *a, const void *b)
{
const loadsave_list_item *itemA = (loadsave_list_item*)a;
const loadsave_list_item *itemB = (loadsave_list_item*)b;
return strcmp(itemA->name, itemB->name);
if (itemA->type != itemB->type)
return itemA->type - itemB->type;
switch (gConfigGeneral.load_save_sort){
case SORT_NAME_ASCENDING:
return compare_string_case_insensitive(itemA->name, itemB->name);
case SORT_NAME_DESCENDING:
return -compare_string_case_insensitive(itemA->name, itemB->name);
case SORT_DATE_DESCENDING:
return (int) -difftime(itemA->date_modified, itemB->date_modified);
case SORT_DATE_ASCENDING:
return (int) difftime(itemA->date_modified, itemB->date_modified);
default:
return compare_string_case_insensitive(itemA->name, itemB->name);
}
}
static void window_loadsave_sort_list(int index, int endIndex)
@ -558,6 +629,8 @@ static void window_loadsave_populate_list(int includeNewItem, bool browsable, co
_listItems = (loadsave_list_item*)malloc(listItemCapacity * sizeof(loadsave_list_item));
_listItemsCount = 0;
bool drivesList = false;
if (browsable) {
int directoryLength = strlen(directory);
int topLevel = 1;
@ -580,6 +653,14 @@ static void window_loadsave_populate_list(int includeNewItem, bool browsable, co
strncpy(listItem->name, language_get_string(2718), sizeof(listItem->name));
memset(listItem->path, '\0', MAX_PATH);
strncpy(listItem->path, directory, lastSlash + 1);
listItem->type = TYPE_UP;
_listItemsCount++;
} else if (platform_get_drives() != 0 && directory[0] != '\0'){
includeNewItem = false;
listItem = &_listItems[_listItemsCount];
strncpy(listItem->name, language_get_string(2718), sizeof(listItem->name));
memset(listItem->path, '\0', MAX_PATH);
listItem->type = TYPE_UP;
_listItemsCount++;
}
}
@ -587,53 +668,78 @@ static void window_loadsave_populate_list(int includeNewItem, bool browsable, co
if (includeNewItem) {
listItem = &_listItems[_listItemsCount];
strncpy(listItem->name, language_get_string(2719), sizeof(listItem->name));
listItem->path[0] = 0;
listItem->path[0] = '\0';
listItem->type = TYPE_NEW_FILE;
_listItemsCount++;
}
int sortStartIndex = _listItemsCount;
fileEnumHandle = platform_enumerate_directories_begin(directory);
while (platform_enumerate_directories_next(fileEnumHandle, subDir)){
if (listItemCapacity <= _listItemsCount) {
listItemCapacity *= 2;
_listItems = realloc(_listItems, listItemCapacity * sizeof(loadsave_list_item));
if (directory[0] != '\0'){
fileEnumHandle = platform_enumerate_directories_begin(directory);
while (platform_enumerate_directories_next(fileEnumHandle, subDir)){
if (listItemCapacity <= _listItemsCount) {
listItemCapacity *= 2;
_listItems = realloc(_listItems, listItemCapacity * sizeof(loadsave_list_item));
}
listItem = &_listItems[_listItemsCount];
memset(listItem->path, '\0', MAX_PATH);
strncpy(listItem->path, directory, MAX_PATH);
strncat(listItem->path, subDir, MAX_PATH);
strncpy(listItem->name, subDir, sizeof(listItem->name));
listItem->type = TYPE_DIRECTORY;
_listItemsCount++;
}
platform_enumerate_files_end(fileEnumHandle);
window_loadsave_sort_list(sortStartIndex, _listItemsCount - 1);
listItem = &_listItems[_listItemsCount];
memset(listItem->path, '\0', MAX_PATH);
strncpy(listItem->path, directory, MAX_PATH);
strncat(listItem->path, subDir, MAX_PATH);
strncpy(listItem->name, subDir, sizeof(listItem->name));
sortStartIndex = _listItemsCount;
fileEnumHandle = platform_enumerate_files_begin(filter);
while (platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
if (listItemCapacity <= _listItemsCount) {
listItemCapacity *= 2;
_listItems = realloc(_listItems, listItemCapacity * sizeof(loadsave_list_item));
}
_listItemsCount++;
listItem = &_listItems[_listItemsCount];
strncpy(listItem->path, directory, sizeof(listItem->path));
strncat(listItem->path, fileInfo.path, sizeof(listItem->path));
listItem->type = TYPE_FILE;
listItem->date_modified = platform_file_get_modified_time(listItem->path);
src = fileInfo.path;
dst = listItem->name;
i = 0;
while (*src != 0 && *src != '.' && i < sizeof(listItem->name) - 1) {
*dst++ = *src++;
i++;
}
*dst = 0;
_listItemsCount++;
}
platform_enumerate_files_end(fileEnumHandle);
} else {
for (int x = 0; x < 32; x++){
if (listItemCapacity <= _listItemsCount) {
listItemCapacity *= 2;
_listItems = realloc(_listItems, listItemCapacity * sizeof(loadsave_list_item));
}
if (platform_get_drives() & (1 << (x))){
listItem = &_listItems[_listItemsCount];
memset(listItem->path, '\0', MAX_PATH);
listItem->path[0] = 'A' + x;
listItem->path[1] = ':';
listItem->path[2] = platform_get_path_separator();
strcpy(listItem->name, listItem->path);
listItem->type = TYPE_DIRECTORY;
_listItemsCount++;
}
}
}
platform_enumerate_files_end(fileEnumHandle);
window_loadsave_sort_list(sortStartIndex, _listItemsCount - 1);
sortStartIndex = _listItemsCount;
fileEnumHandle = platform_enumerate_files_begin(filter);
while (platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
if (listItemCapacity <= _listItemsCount) {
listItemCapacity *= 2;
_listItems = realloc(_listItems, listItemCapacity * sizeof(loadsave_list_item));
}
listItem = &_listItems[_listItemsCount];
strncpy(listItem->path, directory, sizeof(listItem->path));
strncat(listItem->path, fileInfo.path, sizeof(listItem->path));
src = fileInfo.path;
dst = listItem->name;
i = 0;
while (*src != 0 && *src != '.' && i < sizeof(listItem->name) - 1) {
*dst++ = *src++;
i++;
}
*dst = 0;
_listItemsCount++;
}
platform_enumerate_files_end(fileEnumHandle);
window_loadsave_sort_list(sortStartIndex, _listItemsCount - 1);
}