4coder/4ed_file.cpp

379 lines
9.7 KiB
C++

/*
* Mr. 4th Dimention - Allen Webster
*
* 03.01.2017
*
* File layer for 4coder
*
*/
// TOP
//
// Edit Position Basics
//
internal void
edit_pos_set_cursor(File_Edit_Positions *edit_pos, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
edit_pos->cursor = cursor;
if (set_preferred_x){
edit_pos->preferred_x = cursor.wrapped_x;
if (unwrapped_lines){
edit_pos->preferred_x = cursor.unwrapped_x;
}
}
edit_pos->last_set_type = EditPos_CursorSet;
}
internal void
edit_pos_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
edit_pos->scroll = scroll;
edit_pos->last_set_type = EditPos_ScrollSet;
}
//
// Editing_File
//
inline Buffer_Slot_ID
to_file_id(i32 id){
Buffer_Slot_ID result;
result.id = id;
return(result);
}
//
// Handling a file's Marker Arrays
//
internal void
init_file_markers_state(Editing_File_Markers *markers){
Marker_Array *sentinel = &markers->sentinel;
dll_init_sentinel(sentinel);
markers->array_count = 0;
markers->marker_count = 0;
}
internal void
clear_file_markers_state(General_Memory *general, Editing_File_Markers *markers){
Marker_Array *sentinel = &markers->sentinel;
for (Marker_Array *marker_array = sentinel->next;
marker_array != sentinel;
marker_array = sentinel->next){
dll_remove(marker_array);
general_memory_free(general, marker_array);
}
Assert(sentinel->next == sentinel);
Assert(sentinel->prev == sentinel);
markers->array_count = 0;
markers->marker_count = 0;
}
internal void*
allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_array_max){
u32 memory_size = sizeof(Marker_Array) + sizeof(Marker)*new_array_max;
memory_size = l_round_up_u32(memory_size, KB(4));
u32 real_max = (memory_size - sizeof(Marker_Array))/sizeof(Marker);
Marker_Array *array = (Marker_Array*)general_memory_allocate(general, memory_size);
dll_insert_back(&file->markers.sentinel, array);
array->buffer_id = file->id;
array->count = 0;
array->sim_max = new_array_max;
array->max = real_max;
++file->markers.array_count;
return(array);
}
internal Buffer_ID
get_buffer_id_from_marker_handle(void *handle){
Marker_Array *markers = (Marker_Array*)handle;
Buffer_Slot_ID result = markers->buffer_id;
return(result.id);
}
internal b32
markers_set(Editing_File *file, void *handle, u32 first_index, u32 count, Marker *source){
Assert(file != 0);
b32 result = false;
if (handle != 0){
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id == file->id.id){
if (first_index + count <= markers->sim_max){
u32 new_count = first_index + count;
if (new_count > markers->count){
file->markers.marker_count += new_count - markers->count;
markers->count = new_count;
}
Marker *dst = MarkerArrayBase(markers);
memcpy(dst + first_index, source, sizeof(Marker)*count);
result = true;
}
}
}
return(result);
}
internal b32
markers_get(Editing_File *file, void *handle, u32 first_index, u32 count, Marker *output){
Assert(file != 0);
b32 result = false;
if (handle != 0){
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id == file->id.id){
if (first_index + count <= markers->count){
Marker *src = MarkerArrayBase(markers);
memcpy(output, src + first_index, sizeof(Marker)*count);
result = true;
}
}
}
return(result);
}
internal b32
markers_free(General_Memory *general, Editing_File *file, void *handle){
Assert(file != 0);
b32 result = false;
if (handle != 0){
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id == file->id.id){
dll_remove(markers);
file->markers.marker_count -= markers->count;
--file->markers.array_count;
general_memory_free(general, markers);
}
}
return(result);
}
//
// Manipulating a file's Edit_Pos array
//
internal i32
edit_pos_get_index(Editing_File *file, File_Edit_Positions *edit_pos){
i32 edit_pos_index = -1;
i32 count = file->state.edit_poss_count;
File_Edit_Positions **edit_poss = file->state.edit_poss;
for (i32 i = 0; i < count; ++i){
if (edit_poss[i] == edit_pos){
edit_pos_index = i;
break;
}
}
return(edit_pos_index);
}
internal b32
edit_pos_move_to_front(Editing_File *file, File_Edit_Positions *edit_pos){
b32 result = false;
if (file && edit_pos){
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
Assert(edit_pos_index != -1);
File_Edit_Positions **edit_poss = file->state.edit_poss;
memmove(edit_poss + 1, edit_poss, edit_pos_index*sizeof(*edit_poss));
edit_poss[0] = edit_pos;
result = true;
}
return(result);
}
internal b32
edit_pos_unset(Editing_File *file, File_Edit_Positions *edit_pos){
b32 result = false;
if (file && edit_pos){
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
Assert(edit_pos_index != -1);
i32 count = file->state.edit_poss_count;
File_Edit_Positions **edit_poss = file->state.edit_poss;
memmove(edit_poss + edit_pos_index,
edit_poss + edit_pos_index + 1,
(count - edit_pos_index - 1)*sizeof(*edit_poss));
edit_pos->in_view = false;
if (file->state.edit_poss_count > 1){
file->state.edit_poss_count -= 1;
}
result = true;
}
return(result);
}
internal File_Edit_Positions*
edit_pos_get_new(Editing_File *file, i32 index){
File_Edit_Positions *result = 0;
if (file && 0 <= index && index < 16){
result = file->state.edit_pos_space + index;
i32 edit_pos_index = edit_pos_get_index(file, result);
if (edit_pos_index == -1){
File_Edit_Positions **edit_poss = file->state.edit_poss;
i32 count = file->state.edit_poss_count;
if (count > 0){
if (edit_poss[0]->in_view){
memcpy(result, edit_poss[0], sizeof(*result));
memmove(edit_poss+1, edit_poss, sizeof(*edit_poss)*count);
file->state.edit_poss_count = count + 1;
}
else{
Assert(count == 1);
memcpy(result, edit_poss[0], sizeof(*result));
}
}
else{
memset(result, 0, sizeof(*result));
file->state.edit_poss_count = 1;
}
edit_poss[0] = result;
}
result->in_view = true;
}
return(result);
}
//
// Cursor Seeking
//
inline Partial_Cursor
file_compute_cursor_from_pos(Editing_File *file, i32 pos){
Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
return(result);
}
inline Partial_Cursor
file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
return(result);
}
inline b32
file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
b32 result = true;
switch (seek.type){
case buffer_seek_pos:
{
*cursor = file_compute_cursor_from_pos(file, seek.pos);
}break;
case buffer_seek_line_char:
{
*cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
}break;
default:
{
result = false;
}break;
}
return(result);
}
//
// Dirty Flags
//
inline b32
buffer_needs_save(Editing_File *file){
b32 result = 0;
if (!file->settings.unimportant){
if (file->state.dirty == DirtyState_UnsavedChanges){
result = 1;
}
}
return(result);
}
inline b32
buffer_can_save(Editing_File *file){
b32 result = 0;
if (!file->settings.unimportant){
if (file->state.dirty == DirtyState_UnsavedChanges ||
file->state.dirty == DirtyState_UnloadedChanges){
result = 1;
}
}
return(result);
}
inline b32
file_is_ready(Editing_File *file){
b32 result = 0;
if (file && file->is_loading == 0){
result = 1;
}
return(result);
}
inline void
file_set_to_loading(Editing_File *file){
memset(&file->state, 0, sizeof(file->state));
memset(&file->settings, 0, sizeof(file->settings));
file->is_loading = true;
}
inline void
file_mark_clean(Editing_File *file){
if (file->settings.unimportant){
file->state.dirty = DirtyState_UpToDate;
}
else{
if (file->state.dirty != DirtyState_UnloadedChanges){
file->state.dirty = DirtyState_UpToDate;
}
}
}
inline void
file_mark_dirty(Editing_File *file){
if (file->settings.unimportant){
file->state.dirty = DirtyState_UpToDate;
}
else{
if (file->state.dirty != DirtyState_UnloadedChanges){
file->state.dirty = DirtyState_UnsavedChanges;
}
}
}
inline void
file_mark_behind_os(Editing_File *file){
if (file->settings.unimportant){
file->state.dirty = DirtyState_UpToDate;
}
else{
file->state.dirty = DirtyState_UnloadedChanges;
}
}
inline Dirty_State
file_get_sync(Editing_File *file){
return (file->state.dirty);
}
// BOTTOM