diff options
| author | Aldrik Ramaekers <aldrik.ramaekers@protonmail.com> | 2020-01-30 21:11:12 +0100 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrik.ramaekers@protonmail.com> | 2020-01-30 21:11:12 +0100 |
| commit | 260f05025631031b7cc4904805d5017feaf53eda (patch) | |
| tree | d5a723bb7bbbc9f8b598712723fe3d8290c0a54c /src/platform_shared.c | |
initial commit
Diffstat (limited to 'src/platform_shared.c')
| -rw-r--r-- | src/platform_shared.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/src/platform_shared.c b/src/platform_shared.c new file mode 100644 index 0000000..4107ca3 --- /dev/null +++ b/src/platform_shared.c @@ -0,0 +1,244 @@ +/* +* BSD 2-Clause “Simplified” License +* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com +* All rights reserved. +*/ + +void get_name_from_path(char *buffer, char *path) +{ + buffer[0] = 0; + + s32 len = strlen(path); + if (len == 1) + { + return; + } + + char *path_end = path + len; +#ifdef OS_LINUX + while (*path_end != '/' && path_end >= path) + { + --path_end; + } +#endif +#ifdef OS_WIN + while (*path_end != '\\' && path_end >= path) + { + --path_end; + } +#endif + + string_copyn(buffer, path_end+1, MAX_INPUT_LENGTH); +} + +void get_directory_from_path(char *buffer, char *path) +{ + buffer[0] = 0; + + s32 len = strlen(path); + if (len == 1) + { + return; + } + + char *path_end = path + len; +#ifdef OS_LINUX + while (*path_end != '/' && path_end >= path) + { + --path_end; + } +#endif +#ifdef OS_WIN + while (*path_end != '\\' && path_end >= path) + { + --path_end; + } +#endif + + s32 offset = path_end - path; + char ch = path[offset+1]; + path[offset+1] = 0; + string_copyn(buffer, path, MAX_INPUT_LENGTH); + path[offset+1] = ch; +} + +void platform_autocomplete_path(char *buffer, bool want_dir) +{ + char dir[MAX_INPUT_LENGTH]; + char name[MAX_INPUT_LENGTH]; + get_directory_from_path(dir, buffer); + get_name_from_path(name, buffer); + + // nothing to autocomplete + if (name[0] == 0) + { + return; + } + + // create filter + string_appendn(name, "*", MAX_INPUT_LENGTH); + + array files = array_create(sizeof(found_file)); + array filters = get_filters(name); + bool is_cancelled = false; + platform_list_files_block(&files, dir, filters, false, 0, want_dir, &is_cancelled); + + s32 index_to_take = -1; + if (want_dir) + { + for (s32 i = 0; i < files.length; i++) + { + found_file *file = array_at(&files, i); + + if (platform_directory_exists(file->path)) + { + index_to_take = i; + break; + } + } + } + else + { + index_to_take = 0; + } + + array_destroy(&filters); + + if (files.length > 0 && index_to_take != -1) + { + found_file *file = array_at(&files, index_to_take); + string_copyn(buffer, file->path, MAX_INPUT_LENGTH); + } + + for (s32 i = 0; i < files.length; i++) + { + found_file *match = array_at(&files, i); + mem_free(match->matched_filter); + mem_free(match->path); + } + array_destroy(&files); +} + +array get_filters(char *pattern) +{ + array result = array_create(MAX_INPUT_LENGTH); + + char current_filter[MAX_INPUT_LENGTH]; + s32 filter_len = 0; + while(*pattern) + { + char ch = *pattern; + + if (ch == ',') + { + current_filter[filter_len] = 0; + array_push(&result, current_filter); + filter_len = 0; + } + else + { + if(filter_len < MAX_INPUT_LENGTH-1) + { + current_filter[filter_len++] = ch; + } + else + { + current_filter[filter_len] = ch; + } + } + + pattern++; + } + current_filter[filter_len] = 0; + array_push(&result, current_filter); + + return result; +} + +void *platform_list_files_thread(void *args) +{ + list_file_args *info = args; + + array filters = get_filters(info->pattern); + + array *list = info->list; + char *start_dir = info->start_dir; + bool recursive = info->recursive; + + platform_list_files_block(info->list, info->start_dir, filters, info->recursive, info->bucket, info->include_directories, info->is_cancelled); + + mutex_lock(&info->list->mutex); + //if (!(*info->is_cancelled)) + *(info->state) = true; + mutex_unlock(&info->list->mutex); + + array_destroy(&filters); + + return 0; +} + +void platform_list_files(array *list, char *start_dir, char *filter, bool recursive, memory_bucket *bucket, bool *is_cancelled, bool *state) +{ + list_file_args *args = memory_bucket_reserve(bucket, sizeof(list_file_args)); + args->list = list; + args->start_dir = start_dir; + args->pattern = filter; + args->recursive = recursive; + args->state = state; + args->include_directories = 0; + args->bucket = bucket; + args->is_cancelled = is_cancelled; + + thread thr = thread_start(platform_list_files_thread, args); + thread_detach(&thr); +} + +void platform_open_file_dialog(file_dialog_type type, char *buffer, char *file_filter, char *start_path) +{ + struct open_dialog_args *args = mem_alloc(sizeof(struct open_dialog_args)); + args->buffer = buffer; + args->type = type; + args->file_filter = file_filter; + args->start_path = start_path; + + thread thr; + thr.valid = false; + + while (!thr.valid) + thr = thread_start(platform_open_file_dialog_block, args); + thread_detach(&thr); +} + +void destroy_found_file_array(array *found_files) +{ + for (s32 i = 0; i < found_files->length; i++) + { + found_file *f = array_at(found_files, i); + mem_free(f->matched_filter); + mem_free(f->path); + } + array_destroy(found_files); +} + +char *get_file_extension(char *path) +{ + while(*path != '.' && *path) + { + path++; + } + return path; +} + +s32 filter_matches(array *filters, char *string, char **matched_filter) +{ + for (s32 i = 0; i < filters->length; i++) + { + char *filter = array_at(filters, i); + if (string_match(filter, string)) + { + *matched_filter = filter; + return strlen(filter); + } + } + return -1; +} |
