style-system

This commit is contained in:
Allen Webster 2015-09-30 12:32:01 -04:00
parent fb91a10918
commit 852a7fd71c
4 changed files with 604 additions and 197 deletions

124
4ed.cpp
View File

@ -12,8 +12,6 @@
//
// BUGS & PROBLEMS
//
// - LOGGING SYSTEM FOR ALL BUILD CONFIGS
//
// - line_wrap_ys remeasurement optimization
//
// GENERAL
@ -31,8 +29,6 @@
//
// - configuration / GUI for generating configuration
//
// - no scroll on line wrap/line mode change
//
// - travel packaging
//
// - multiple live name conflicts
@ -63,8 +59,6 @@
//
// - select token
//
// - seek token or whitespace within token
//
// - reprogrammable lexing / auto indent
//
// - bracket match / mismatch highlighting
@ -89,9 +83,7 @@
// - generate header
//
/*
* App Structs
*/
// App Structs
enum App_State{
APP_STATE_EDIT,
@ -142,9 +134,7 @@ struct App_Vars{
Panel *prev_mouse_panel;
};
/*
* Commands
*/
// Commands
globalvar Application_Links app_links;
@ -235,7 +225,7 @@ COMMAND_DECL(write_character){
current_view->preferred_x = view_get_cursor_x(current_view);
}
}
file->cursor.pos = view->cursor.pos;
file->cursor_pos = view->cursor.pos;
}
internal i32
@ -733,10 +723,7 @@ COMMAND_DECL(paste_next){
view_measure_wraps(&mem->general, view);
view->cursor = view_compute_cursor_from_pos(view, range.smaller+src->size);
view->preferred_x = view_get_cursor_x(view);
view->file->cursor.pos = view->cursor.pos;
view_cursor_move(view, range.smaller+src->size);
view->mark = pos_universal_fix(range.smaller,
file->data, file->size,
file->endline_mode);
@ -792,11 +779,10 @@ COMMAND_DECL(delete_chunk){
}
buffer_delete_range(mem, file, range);
view_measure_wraps(&mem->general, view);
view->cursor = view_compute_cursor_from_pos(view, range.smaller);
view_cursor_move(view, range.smaller);
view->mark = pos_universal_fix(range.smaller,
file->data, file->size,
file->endline_mode);
view->file->cursor.pos = view->cursor.pos;
Editing_Layout *layout = command->layout;
Panel *panels = layout->panels;
@ -828,6 +814,49 @@ COMMAND_DECL(delete_chunk){
}
}
COMMAND_DECL(undo){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
USE_MEM(mem);
if (file->undo.edit_count > 0){
Edit_Step step = file->undo.edits[--file->undo.edit_count];
buffer_post_redo(&mem->general, file, step.range.start, step.range.end, step.replaced.size);
buffer_replace_range(mem, file, step.range.start, step.range.end,
(u8*)step.replaced.str, step.replaced.size, 0);
view_cursor_move(view, step.cursor_pos);
view->mark = view->cursor.pos;
view_post_paste_effect(view, 10, step.range.start, step.replaced.size,
view->style->main.undo_color);
file->undo.str_size -= step.replaced.size;
}
}
COMMAND_DECL(redo){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
USE_MEM(mem);
if (file->undo.edit_redo < file->undo.edit_max){
Edit_Step step = file->undo.edits[file->undo.edit_redo++];
buffer_replace_range(mem, file, step.range.start, step.range.end,
(u8*)step.replaced.str, step.replaced.size, 2);
view_cursor_move(view, step.cursor_pos);
view->mark = view->cursor.pos;
view_post_paste_effect(view, 10, step.range.start, step.replaced.size,
view->style->main.undo_color);
file->undo.str_redo += step.replaced.size;
}
}
COMMAND_DECL(interactive_new){
ProfileMomentFunction();
USE_VARS(vars);
@ -1132,6 +1161,7 @@ COMMAND_DECL(to_lowercase){
}
}
#if 0
internal void
view_clean_line(Mem_Options *mem, File_View *view, Editing_File *file, i32 line_start){
u8 *data = file->data;
@ -1188,8 +1218,10 @@ view_clean_line(Mem_Options *mem, File_View *view, Editing_File *file, i32 line_
//view_auto_tab(mem, view, pos, pos);
}
}
#endif
COMMAND_DECL(clean_line){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -1198,9 +1230,11 @@ COMMAND_DECL(clean_line){
i32 line_start = view_find_beginning_of_line(view, view->cursor.pos);
view_clean_line(mem, view, file, line_start);
view_measure_wraps(&mem->general, view);
#endif
}
COMMAND_DECL(clean_all_lines){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -1213,9 +1247,11 @@ COMMAND_DECL(clean_all_lines){
view_measure_wraps(&mem->general, view);
view->cursor = view_compute_cursor_from_pos(view, view->cursor.pos);
#endif
}
COMMAND_DECL(eol_dosify){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -1223,9 +1259,11 @@ COMMAND_DECL(eol_dosify){
view_endline_convert(mem, view, ENDLINE_RN, ENDLINE_ERASE, ENDLINE_RN);
view_measure_wraps(&mem->general, view);
#endif
}
COMMAND_DECL(eol_nixify){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -1233,17 +1271,19 @@ COMMAND_DECL(eol_nixify){
view_endline_convert(mem, view, ENDLINE_N, ENDLINE_ERASE, ENDLINE_N);
view_measure_wraps(&mem->general, view);
#endif
}
COMMAND_DECL(auto_tab){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
USE_MEM(mem);
Range range = get_range(view->cursor.pos, view->mark);
view_auto_tab(mem, view, range.smaller, range.larger);
view_measure_wraps(&mem->general, view);
#endif
}
COMMAND_DECL(open_panel_vsplit){
@ -1541,7 +1581,7 @@ COMMAND_DECL(move_up){
real32 px = view->preferred_x;
if (cy >= 0){
view->cursor = view_compute_cursor_from_xy(view, px, cy);
view->file->cursor.pos = view->cursor.pos;
view->file->cursor_pos = view->cursor.pos;
}
}
@ -1553,7 +1593,7 @@ COMMAND_DECL(move_down){
real32 cy = view_get_cursor_y(view)+view->style->font->height;
real32 px = view->preferred_x;
view->cursor = view_compute_cursor_from_xy(view, px, cy);
view->file->cursor.pos = view->cursor.pos;
view->file->cursor_pos = view->cursor.pos;
}
COMMAND_DECL(seek_end_of_line){
@ -1709,12 +1749,15 @@ COMMAND_DECL(cursor_mark_swap){
view->mark = pos;
}
internal void
fulfill_interaction(Command_Data *command, char *data, bool32 full_set){
internal bool32
fulfill_interaction_intview(Command_Data *command, char *data, bool32 full_set){
bool32 result = 0;
Panel *panel = command->panel;
View *view = panel->view;
Interactive_View *int_view = view_to_interactive_view(view);
if (int_view){
result = 1;
String *dest = 0;
switch (int_view->interaction){
case INTV_SYS_FILE_LIST:
@ -1726,11 +1769,13 @@ fulfill_interaction(Command_Data *command, char *data, bool32 full_set){
}
if (full_set) dest->size = 0;
append(dest, data);
}
interactive_view_complete(int_view);
}
return result;
}
COMMAND_DECL(user_callback){
ProfileMomentFunction();
if (binding.custom) binding.custom(command, app_links);
@ -1766,7 +1811,8 @@ extern "C"{
FULFILL_INTERACTION_SIG(fulfill_interaction_external){
Command_Data *cmd = (Command_Data*)cmd_context;
fulfill_interaction(cmd, data, full_set);
bool32 handled = 0;
handled = fulfill_interaction_intview(cmd, data, full_set);
}
}
@ -1829,6 +1875,8 @@ setup_file_commands(Command_Map *commands, Key_Codes *codes){
map_add(commands, 'x', MDFR_CTRL, command_cut);
map_add(commands, 'v', MDFR_CTRL, command_paste);
map_add(commands, 'V', MDFR_CTRL, command_paste_next);
map_add(commands, 'z', MDFR_CTRL, command_undo);
map_add(commands, 'y', MDFR_CTRL, command_redo);
map_add(commands, 'd', MDFR_CTRL, command_delete_chunk);
map_add(commands, 'l', MDFR_CTRL, command_toggle_line_wrap);
map_add(commands, 'L', MDFR_CTRL, command_toggle_endline_mode);
@ -1956,9 +2004,7 @@ setup_command_table(){
#undef SET
}
/*
* Interactive Bar
*/
// Interactive Bar
internal void
hot_directory_draw_helper(Render_Target *target,
@ -2074,12 +2120,14 @@ app_hardcode_styles(App_Vars *vars){
style->main.special_character_color = 0xFFFF0000;
style->main.paste_color = 0xFFDDEE00;
style->main.undo_color = 0xFF00DDEE;
style->main.next_undo_color = 0xFF006E77;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xff003a3a;
file_info_style.bar_color = 0xFF888888;
file_info_style.bar_active_color = 0xFF888888;
file_info_style.bar_active_color = 0xFF666666;
file_info_style.base_color = 0xFF000000;
file_info_style.pop1_color = 0xFF4444AA;
file_info_style.pop2_color = 0xFFFF0000;
@ -2119,12 +2167,14 @@ app_hardcode_styles(App_Vars *vars){
style->main.special_character_color = 0xFFFF0000;
style->main.paste_color = 0xFFFFBB00;
style->main.undo_color = 0xFFFF00BB;
style->main.undo_color = 0xFF80005D;
style->main.highlight_junk_color = 0xFF3A0000;
style->main.highlight_white_color = 0xFF003A3A;
file_info_style.bar_color = 0xFFCACACA;
file_info_style.bar_active_color = 0xFFCACACA;
file_info_style.bar_active_color = 0xFFA8A8A8;
file_info_style.base_color = 0xFF000000;
file_info_style.pop1_color = 0xFF1504CF;
file_info_style.pop2_color = 0xFFFF0000;
@ -2158,12 +2208,14 @@ app_hardcode_styles(App_Vars *vars){
style->main.special_character_color = 0xFFFF0000;
style->main.paste_color = 0xFFDDEE00;
style->main.undo_color = 0xFF00DDEE;
style->main.next_undo_color = 0xFF006E77;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xFF151F2A;
file_info_style.bar_color = 0xFF315E68;
file_info_style.bar_active_color = 0xFF315E68;
file_info_style.bar_active_color = 0xFF0F3C46;
file_info_style.base_color = 0xFF000000;
file_info_style.pop1_color = 0xFF1BFF0C;
file_info_style.pop2_color = 0xFFFF200D;
@ -2197,12 +2249,14 @@ app_hardcode_styles(App_Vars *vars){
style->main.special_character_color = 0xFFFF0000;
style->main.paste_color = 0xFF900090;
style->main.undo_color = 0xFF606090;
style->main.next_undo_color = 0xFF404070;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xff003a3a;
file_info_style.bar_color = 0xFF7082F9;
file_info_style.bar_active_color = 0xFF7082F9;
file_info_style.bar_active_color = 0xFF4E60D7;
file_info_style.base_color = 0xFF000000;
file_info_style.pop1_color = 0xFFFAFA15;
file_info_style.pop2_color = 0xFFD20000;
@ -2236,12 +2290,14 @@ app_hardcode_styles(App_Vars *vars){
style->main.special_character_color = 0xFF9A0000;
style->main.paste_color = 0xFF00B8B8;
style->main.undo_color = 0xFFB800B8;
style->main.next_undo_color = 0xFF5C005C;
style->main.highlight_junk_color = 0xFFFF7878;
style->main.highlight_white_color = 0xFFBCBCBC;
file_info_style.bar_color = 0xFF606060;
file_info_style.bar_active_color = 0xFF888888;
file_info_style.bar_active_color = 0xFF3E3E3E;
file_info_style.base_color = 0xFF000000;
file_info_style.pop1_color = 0xFF1111DC;
file_info_style.pop2_color = 0xFFE80505;

View File

@ -60,6 +60,8 @@ draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32
case BUBBLE_WIDTHS: append(&s, "widths"); break;
case BUBBLE_WRAPS: append(&s, "wraps"); break;
case BUBBLE_TOKENS: append(&s, "tokens"); break;
case BUBBLE_UNDO_STRING: append(&s, "undo string"); break;
case BUBBLE_UNDO: append(&s, "undo"); break;
default: append(&s, "unknown"); break;
}
}

View File

@ -9,20 +9,45 @@
// TOP
struct Cursor_Data{
i32 pos;
};
enum Endline_Mode{
ENDLINE_RN_COMBINED,
ENDLINE_RN_SEPARATE,
ENDLINE_RN_SHOWALLR
};
struct Range{
union{
struct{
i32 smaller, larger;
};
struct{
i32 start, end;
};
};
bool32 swapped;
};
struct Edit_Step{
String replaced;
Range range;
i32 cursor_pos;
bool32 can_merge;
};
struct Undo_Data{
i32 str_size, str_redo, str_max;
u8 *strings;
i32 edit_count, edit_redo, edit_max;
Edit_Step *edits;
};
struct Editing_File{
i32 size, max_size;
u8 *data;
Undo_Data undo;
i32 line_count, line_max;
i32 *line_starts;
@ -31,7 +56,7 @@ struct Editing_File{
real32 *line_width;
Endline_Mode endline_mode;
Cursor_Data cursor;
i32 cursor_pos;
bool32 is_dummy;
char source_path_[256];
@ -215,18 +240,6 @@ struct File_View{
Text_Effect paste_effect;
};
struct Range{
union{
struct{
i32 smaller, larger;
};
struct{
i32 start, end;
};
};
bool32 swapped;
};
inline File_View*
view_to_file_view(View *view){
File_View* result = 0;
@ -388,6 +401,8 @@ enum File_Bubble_Type{
BUBBLE_WIDTHS,
BUBBLE_WRAPS,
BUBBLE_TOKENS,
BUBBLE_UNDO_STRING,
BUBBLE_UNDO,
//
FILE_BUBBLE_TYPE_END,
};
@ -689,7 +704,7 @@ view_measure_wraps(General_Memory *general, File_View *view){
internal void
buffer_create_from_string(General_Memory *general, Editing_File *file, u8 *filename, Font *font, String val){
i32 request_size = LargeRoundUp(1+val.size*2, Kbytes(256));
i32 request_size = LargeRoundUp(1+val.size*2, Kbytes(64));
u8 *data = (u8*)general_memory_allocate(general, request_size, BUBBLE_BUFFER);
// TODO(allen): if we didn't get the memory what is going on?
@ -714,6 +729,14 @@ buffer_create_from_string(General_Memory *general, Editing_File *file, u8 *filen
buffer_measure_widths(general, file, font);
file->font = font;
file->undo.str_max = request_size;
file->undo.str_redo = file->undo.str_max;
file->undo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING);
file->undo.edit_max = request_size / sizeof(Edit_Step);
file->undo.edit_redo = file->undo.edit_max;
file->undo.edits = (Edit_Step*)general_memory_allocate(general, request_size, BUBBLE_UNDO);
if (!match(file->extension, make_lit_string("txt"))){
file->tokens_exist = 1;
}
@ -789,12 +812,6 @@ buffer_get_dummy(Editing_File *buffer){
buffer->is_dummy = 1;
}
enum Replace_Operation_Type{
REP_UNKNOWN,
REP_REGULAR,
REP_WHITESPACE
};
struct Shift_Information{
i32 start, end, amount;
};
@ -955,7 +972,6 @@ buffer_relex_parallel(Mem_Options *mem, Editing_File *file,
}
if (!inline_lex){
// TODO(allen): duplicated see REP_WHITESPACE
i32 end_token_i = cpp_get_end_token(&file->token_stack, end_i);
cpp_shift_token_starts(&file->token_stack, end_token_i, amount);
--end_token_i;
@ -997,73 +1013,171 @@ buffer_grow_as_needed(General_Memory *general, Editing_File *file, i32 additiona
return result;
}
inline void
buffer_grow_undo_string(General_Memory *general, Editing_File *file, i32 extra_size){
i32 old_max = file->undo.str_max;
u8 *old_str = file->undo.strings;
i32 redo_size = old_max - file->undo.str_redo;
i32 new_max = old_max*2 + extra_size;
u8 *new_str = (u8*)
general_memory_allocate(general, new_max, BUBBLE_UNDO_STRING);
i32 new_redo = new_max - redo_size;
memcpy(new_str, old_str, file->undo.str_size);
memcpy(new_str + new_redo, old_str + file->undo.str_redo, redo_size);
general_memory_free(general, old_str);
file->undo.strings = new_str;
file->undo.str_max = new_max;
file->undo.str_redo = new_redo;
}
inline void
buffer_grow_undo_edits(General_Memory *general, Editing_File *file){
i32 old_max = file->undo.edit_max;
Edit_Step *old_eds = file->undo.edits;
i32 redo_size = old_max - file->undo.edit_redo;
i32 new_max = old_max*2 + 2;
Edit_Step *new_eds = (Edit_Step*)
general_memory_allocate(general, new_max*sizeof(Edit_Step), BUBBLE_UNDO);
i32 new_redo = new_max - redo_size;
memcpy(new_eds, old_eds, file->undo.edit_count*sizeof(Edit_Step));
memcpy(new_eds + new_redo, old_eds, redo_size*sizeof(Edit_Step));
general_memory_free(general, old_eds);
file->undo.edits = new_eds;
file->undo.edit_max = new_max;
file->undo.edit_redo = new_redo;
}
inline void
buffer_post_undo(General_Memory *general, Editing_File *file,
i32 start, i32 end, i32 str_len, bool32 do_merge, bool32 can_merge,
bool32 clear_redo){
String replaced = make_string((char*)file->data + start, end - start);
if (clear_redo){
file->undo.str_redo = file->undo.str_max;
file->undo.edit_redo = file->undo.edit_max;
}
if (file->undo.str_redo < file->undo.str_size + replaced.size)
buffer_grow_undo_string(general, file, replaced.size);
Edit_Step edit;
edit.replaced = make_string((char*)file->undo.strings + file->undo.str_size, replaced.size);
file->undo.str_size += replaced.size;
copy(&edit.replaced, replaced);
edit.range = {start, start + str_len, 0};
edit.cursor_pos = file->cursor_pos;
edit.can_merge = can_merge;
bool32 did_merge = 0;
if (do_merge && file->undo.edit_count > 0){
Edit_Step prev = file->undo.edits[file->undo.edit_count-1];
if (prev.can_merge && edit.replaced.size == 0 && prev.replaced.size == 0){
if (prev.range.end == edit.range.start){
did_merge = 1;
edit.range.start = prev.range.start;
edit.cursor_pos = prev.cursor_pos;
}
}
}
if (did_merge){
file->undo.edits[file->undo.edit_count-1] = edit;
}
else{
if (file->undo.edit_redo <= file->undo.edit_count)
buffer_grow_undo_edits(general, file);
file->undo.edits[file->undo.edit_count++] = edit;
}
}
inline void
buffer_post_redo(General_Memory *general, Editing_File *file,
i32 start, i32 end, i32 str_len){
String replaced = make_string((char*)file->data + start, end - start);
if (file->undo.str_redo - replaced.size < file->undo.str_size)
buffer_grow_undo_string(general, file, replaced.size);
file->undo.str_redo -= replaced.size;
TentativeAssert(file->undo.str_redo >= file->undo.str_size);
Edit_Step edit;
edit.replaced = make_string((char*)file->undo.strings + file->undo.str_redo, replaced.size);
copy(&edit.replaced, replaced);
edit.range = {start, start + str_len, 0};
edit.cursor_pos = file->cursor_pos;
if (file->undo.edit_redo <= file->undo.edit_count)
buffer_grow_undo_edits(general, file);
--file->undo.edit_redo;
file->undo.edits[file->undo.edit_redo] = edit;
}
inline i32
buffer_text_replace(General_Memory *general, Editing_File *file,
i32 start, i32 end, u8 *str, i32 str_len){
i32 shift_amount = (str_len - (end - start));
buffer_grow_as_needed(general, file, shift_amount);
Assert(shift_amount + file->size < file->max_size);
i32 size = file->size;
u8 *data = (u8*)file->data;
memmove(data + end + shift_amount, data + end, size - end);
file->size += shift_amount;
memcpy(data + start, str, str_len);
return shift_amount;
}
// TODO(allen): Proper strings?
internal Shift_Information
buffer_replace_range(Mem_Options *mem, Editing_File *file,
i32 start, i32 end, u8 *str, i32 str_len,
Replace_Operation_Type op_type = REP_UNKNOWN){
i32 save_undo = 1){
ProfileMomentFunction();
General_Memory *general = &mem->general;
Shift_Information shift = {};
shift.start = start;
shift.end = end;
shift.amount = (str_len - (end - start));
// TODO(allen): Quickly figure out which op type is appropriate?
// Or just assume REGULAR, as that is always correct?
buffer_grow_as_needed(general, file, shift.amount);
Assert(shift.amount + file->size < file->max_size);
if (file->still_lexing){
if (file->still_lexing)
system_cancel_job(BACKGROUND_THREADS, file->lex_job);
}
file->last_4ed_edit_time = system_get_now();
i32 size = file->size;
u8 *data = (u8*)file->data;
memmove(data + shift.end + shift.amount, data + shift.end, size - end);
file->size += shift.amount;
memcpy(data + start, str, str_len);
if (file->tokens_exist){
switch (op_type){
case REP_UNKNOWN:
case REP_REGULAR:
{
buffer_relex_parallel(mem, file, start, end, shift.amount);
}break;
case REP_WHITESPACE:
{
// TODO(allen): duplicated see buffer_relex_parallel
i32 end_token_i = cpp_get_end_token(&file->token_stack, end);
cpp_shift_token_starts(&file->token_stack, end_token_i, shift.amount);
--end_token_i;
if (end_token_i >= 0){
Cpp_Token *token = file->token_stack.tokens + end_token_i;
if (token->start < end && token->start + token->size > end){
token->size += shift.amount;
}
}
}break;
}
General_Memory *general = &mem->general;
if (save_undo){
bool32 can_merge = 0, do_merge = 0;
if (str_len == 1 && char_is_alpha_numeric(*str)) can_merge = 1;
if (str_len == 1 && (can_merge || char_is_whitespace(*str))) do_merge = 1;
buffer_post_undo(general, file, start, end, str_len, do_merge, can_merge, save_undo == 1);
}
i32 line_start = buffer_get_line_index(file, shift.start);
i32 line_end = buffer_get_line_index(file, shift.end);
i32 shift_amount = buffer_text_replace(general, file, start, end, str, str_len);
if (file->tokens_exist)
buffer_relex_parallel(mem, file, start, end, shift_amount);
i32 line_start = buffer_get_line_index(file, start);
i32 line_end = buffer_get_line_index(file, end);
i32 replaced_line_count = line_end - line_start;
i32 new_line_count = buffer_count_newlines(file, shift.start, shift.start+str_len);
i32 new_line_count = buffer_count_newlines(file, start, start+str_len);
i32 line_shift = new_line_count - replaced_line_count;
buffer_remeasure_starts(general, file, line_start, line_end, line_shift, shift.amount);
buffer_remeasure_starts(general, file, line_start, line_end, line_shift, shift_amount);
// TODO(allen): Can we "remeasure" widths now!?
buffer_measure_widths(general, file, file->font);
Shift_Information shift;
shift.start = start;
shift.end = end;
shift.amount = shift_amount;
return shift;
}
@ -1490,7 +1604,7 @@ view_set_file(File_View *view, Editing_File *file, Style *style){
view_measure_wraps(general, view);
view->cursor = {};
view->cursor = view_compute_cursor_from_pos(view, file->cursor.pos);
view->cursor = view_compute_cursor_from_pos(view, file->cursor_pos);
real32 cursor_x, cursor_y;
real32 w, h;
@ -1555,7 +1669,7 @@ inline void
view_cursor_move(File_View *view, View_Cursor_Data cursor){
view->cursor = cursor;
view->preferred_x = view_get_cursor_x(view);
view->file->cursor.pos = view->cursor.pos;
view->file->cursor_pos = view->cursor.pos;
view->show_temp_highlight = 0;
}
@ -1563,7 +1677,7 @@ inline void
view_cursor_move(File_View *view, i32 pos){
view->cursor = view_compute_cursor_from_pos(view, pos);
view->preferred_x = view_get_cursor_x(view);
view->file->cursor.pos = view->cursor.pos;
view->file->cursor_pos = view->cursor.pos;
view->show_temp_highlight = 0;
}
@ -1576,7 +1690,7 @@ view_cursor_move(File_View *view, real32 x, real32 y, bool32 round_down = 0){
view->cursor = view_compute_cursor_from_wrapped_xy(view, x, y, round_down);
}
view->preferred_x = view_get_cursor_x(view);
view->file->cursor.pos = view->cursor.pos;
view->file->cursor_pos = view->cursor.pos;
view->show_temp_highlight = 0;
}
@ -1721,6 +1835,7 @@ clipboard_copy(General_Memory *general, Working_Set *working, u8 *data, Range ra
system_post_clipboard(*dest);
}
#if 0
internal void
view_endline_convert(Mem_Options *mem, File_View *view,
Endline_Convert_Type rn_to,
@ -1766,8 +1881,7 @@ view_endline_convert(Mem_Options *mem, File_View *view,
if (rn_to != ENDLINE_RN){
buffer_replace_range(mem, file, i, i+2,
eol_strings[rn_to].str,
eol_strings[rn_to].size,
REP_WHITESPACE);
eol_strings[rn_to].size);
i32 shift = eol_strings[rn_to].size - 2;
if (cursor >= i){
cursor += shift;
@ -1785,8 +1899,7 @@ view_endline_convert(Mem_Options *mem, File_View *view,
if (r_to != ENDLINE_R){
buffer_replace_range(mem, file, i, i+1,
eol_strings[r_to].str,
eol_strings[r_to].size,
REP_WHITESPACE);
eol_strings[r_to].size);
i32 shift = eol_strings[r_to].size - 1;
if (cursor >= i){
cursor += shift;
@ -1803,8 +1916,7 @@ view_endline_convert(Mem_Options *mem, File_View *view,
if (n_to != ENDLINE_N){
buffer_replace_range(mem, file, i, i+1,
eol_strings[n_to].str,
eol_strings[n_to].size,
REP_WHITESPACE);
eol_strings[n_to].size);
i32 shift = eol_strings[n_to].size - 1;
if (cursor >= i){
cursor += shift;
@ -1821,6 +1933,7 @@ view_endline_convert(Mem_Options *mem, File_View *view,
view->cursor = view_compute_cursor_from_pos(view, cursor);
view->mark = mark;
}
#endif
struct Indent_Definition{
i32 tabs, spaces;
@ -1860,6 +1973,7 @@ buffer_find_hard_start(Editing_File *file, i32 line_start){
return result;
}
#if 0
// NOTE(allen): Assumes that whitespace_buffer has at least
// indent.tabs*4 + indent.spaces bytes available.
internal Shift_Information
@ -1885,7 +1999,7 @@ buffer_set_indent_whitespace(Mem_Options *mem, Editing_File *file,
if (leading_white.smaller < leading_white.larger){
shift = buffer_replace_range(mem, file,
leading_white.smaller, leading_white.larger,
whitespace_buffer, i, REP_WHITESPACE);
whitespace_buffer, i);
}
return shift;
@ -2005,7 +2119,9 @@ buffer_compute_nest_level_tokens(Editing_File *file, i32 pos, Nest_Level_Hint hi
}
return result;
}
#endif
#if 0
internal void
view_auto_tab(Mem_Options *mem, File_View *view, i32 start, i32 end){
Editing_File *file = view->file;
@ -2258,6 +2374,7 @@ view_auto_tab(Mem_Options *mem, File_View *view, i32 start, i32 end){
view_cursor_move(view, cursor);
view->mark = pos_adjust_to_self(mark, data, file->size);
}
#endif
internal u32*
style_get_color(Style *style, Cpp_Token token){
@ -2458,62 +2575,6 @@ step_file_view(Thread_Context *thread, View *view_, i32_Rect rect,
return result;
}
internal void
file_view_intbar(Thread_Context *thread, Render_Target *target,
Interactive_Bar *bar, File_View *view,
Editing_File *file, Style *style){
i32 w, h;
w = bar->rect.x1 - bar->rect.x0;
h = bar->rect.y1 - bar->rect.y0;
u32 back_color = bar->style.bar_color;
draw_rectangle(target, bar->rect, back_color);
u32 base_color = bar->style.base_color;
intbar_draw_string(target, bar, file->live_name, base_color);
intbar_draw_string(target, bar, make_lit_string(" - "), base_color);
char line_number_space[30];
String line_number = make_string(line_number_space, 0, 30);
append(&line_number, "L#");
append_int_to_str(view->cursor.line, &line_number);
intbar_draw_string(target, bar, line_number, base_color);
switch (view->state){
case FVIEW_STATE_EDIT:
{
if (file->last_4ed_write_time != file->last_sys_write_time){
persist String out_of_sync = make_lit_string(" BEHIND OS");
intbar_draw_string(target, bar, out_of_sync, bar->style.pop2_color);
}
else if (file->last_4ed_edit_time > file->last_sys_write_time){
persist String out_of_sync = make_lit_string(" *");
intbar_draw_string(target, bar, out_of_sync, bar->style.pop2_color);
}
}break;
case FVIEW_STATE_SEARCH:
{
persist String search_str = make_lit_string(" I-Search: ");
persist String rsearch_str = make_lit_string(" Reverse-I-Search: ");
if (view->isearch.reverse){
intbar_draw_string(target, bar, rsearch_str, bar->style.pop1_color);
}
else{
intbar_draw_string(target, bar, search_str, bar->style.pop1_color);
}
intbar_draw_string(target, bar, view->isearch.str, bar->style.base_color);
}break;
case FVIEW_STATE_GOTO_LINE:
{
persist String gotoline_str = make_lit_string(" Goto Line: ");
intbar_draw_string(target, bar, gotoline_str, bar->style.pop1_color);
intbar_draw_string(target, bar, view->isearch.str, bar->style.base_color);
}break;
}
}
internal i32
draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_active,
Render_Target *target){
@ -2601,7 +2662,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
real32 fade_amount = 0.f;
if (view->paste_effect.tick_down > 0 &&
view->paste_effect.start <= i && i < view->paste_effect.end){
fade_color = style->main.paste_color;
fade_color = view->paste_effect.color;
fade_amount = (real32)(view->paste_effect.tick_down) / view->paste_effect.tick_max;
}
@ -2765,7 +2826,69 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
}
}
file_view_intbar(thread, target, &bar, view, file, style);
{
Interactive_Bar bar2;
bar2.style = style->main.file_info_style;
bar2.font = style->font;
bar2.pos_x = (real32)rect.x0;
bar2.pos_y = (real32)rect.y0 + 3;
bar2.text_shift_y = 0;
bar2.text_shift_x = 0;
bar2.rect = rect;
bar2.rect.y1 = bar2.rect.y0 + font->height + 2;
switch (view->state){
case FVIEW_STATE_SEARCH:
{
draw_rectangle(target, bar2.rect, bar2.style.bar_active_color);
persist String search_str = make_lit_string("I-Search: ");
persist String rsearch_str = make_lit_string("Reverse-I-Search: ");
if (view->isearch.reverse){
intbar_draw_string(target, &bar2, rsearch_str, bar2.style.pop1_color);
}
else{
intbar_draw_string(target, &bar2, search_str, bar2.style.pop1_color);
}
intbar_draw_string(target, &bar2, view->isearch.str, bar2.style.base_color);
}break;
case FVIEW_STATE_GOTO_LINE:
{
draw_rectangle(target, bar2.rect, bar2.style.bar_active_color);
persist String gotoline_str = make_lit_string("Goto Line: ");
intbar_draw_string(target, &bar2, gotoline_str, bar2.style.pop1_color);
intbar_draw_string(target, &bar2, view->isearch.str, bar2.style.base_color);
}break;
}
}
{
u32 back_color = bar.style.bar_color;
draw_rectangle(target, bar.rect, back_color);
u32 base_color = bar.style.base_color;
intbar_draw_string(target, &bar, file->live_name, base_color);
intbar_draw_string(target, &bar, make_lit_string(" - "), base_color);
char line_number_space[30];
String line_number = make_string(line_number_space, 0, 30);
append(&line_number, "L#");
append_int_to_str(view->cursor.line, &line_number);
intbar_draw_string(target, &bar, line_number, base_color);
if (file->last_4ed_write_time != file->last_sys_write_time){
persist String out_of_sync = make_lit_string(" BEHIND OS");
intbar_draw_string(target, &bar, out_of_sync, bar.style.pop2_color);
}
else if (file->last_4ed_edit_time > file->last_sys_write_time){
persist String out_of_sync = make_lit_string(" *");
intbar_draw_string(target, &bar, out_of_sync, bar.style.pop2_color);
}
}
return 0;
}

View File

@ -118,11 +118,97 @@ struct Style_File_Format_v3{
Style_Main_Data_v3 main;
};
struct Style_Main_Data{
u32 back_color;
u32 margin_color;
u32 margin_hover_color;
u32 margin_active_color;
u32 cursor_color;
u32 at_cursor_color;
u32 highlight_color;
u32 at_highlight_color;
u32 mark_color;
u32 default_color;
u32 comment_color;
u32 keyword_color;
u32 str_constant_color;
u32 char_constant_color;
u32 int_constant_color;
u32 float_constant_color;
u32 bool_constant_color;
u32 preproc_color;
u32 include_color;
u32 special_character_color;
u32 highlight_junk_color;
u32 highlight_white_color;
u32 paste_color;
u32 undo_color;
u32 next_undo_color;
Interactive_Style file_info_style;
};
struct Style_File_Format_v4{
i32 name_size;
char name[24];
i32 font_name_size;
char font_name[24];
Style_Main_Data main;
};
enum Style_Color_Tag{
STAG_BAR_COLOR,
STAG_BAR_ACTIVE_COLOR,
STAG_BAR_BASE_COLOR,
STAG_BAR_POP1_COLOR,
STAG_BAR_POP2_COLOR,
STAG_BACK_COLOR,
STAG_MARGIN_COLOR,
STAG_MARGIN_HOVER_COLOR,
STAG_MARGIN_ACTIVE_COLOR,
STAG_CURSOR_COLOR,
STAG_AT_CURSOR_COLOR,
STAG_HIGHLIGHT_COLOR,
STAG_AT_HIGHLIGHT_COLOR,
STAG_MARK_COLOR,
STAG_DEFAULT_COLOR,
STAG_COMMENT_COLOR,
STAG_KEYWORD_COLOR,
STAG_STR_CONSTANT_COLOR,
STAG_CHAR_CONSTANT_COLOR,
STAG_INT_CONSTANT_COLOR,
STAG_FLOAT_CONSTANT_COLOR,
STAG_BOOL_CONSTANT_COLOR,
STAG_PREPROC_COLOR,
STAG_INCLUDE_COLOR,
STAG_SPECIAL_CHARACTER_COLOR,
STAG_HIGHLIGHT_JUNK_COLOR,
STAG_HIGHLIGHT_WHITE_COLOR,
STAG_PASTE_COLOR,
STAG_UNDO_COLOR,
STAG_NEXT_UNDO_COLOR,
// never below this
STAG_COUNT
};
struct Style_Color_Specifier{
u32 tag;
u32 color;
};
struct Style_File_Format{
i32 name_size;
char name[24];
i32 font_name_size;
char font_name[24];
i32 color_specifier_count;
};
struct Style{
char name_[24];
String name;
Font *font;
Style_Main_Data_v3 main;
Style_Main_Data main;
bool32 font_changed;
};
@ -232,30 +318,148 @@ style_form_convert(Style_File_Format_v3 *o, Style_File_Format_v2 *i){
o->main.file_info_style = i->main.file_info_style;
}
typedef Style_Main_Data_v3 Style_Main_Data;
typedef Style_File_Format_v3 Style_File_Format;
internal void
style_form_convert(Style_File_Format_v4 *o, Style_File_Format_v3 *i){
o->name_size = i->name_size;
memcpy(o->name, i->name, i->name_size);
o->font_name_size = i->font_name_size;
memcpy(o->font_name, i->font_name, i->font_name_size);
o->main.back_color = i->main.back_color;
o->main.margin_color = i->main.margin_color;
o->main.margin_hover_color = i->main.margin_hover_color;
o->main.margin_active_color = i->main.margin_active_color;
o->main.cursor_color = i->main.cursor_color;
o->main.at_cursor_color = i->main.at_cursor_color;
o->main.highlight_color = i->main.highlight_color;
o->main.at_highlight_color = i->main.at_highlight_color;
o->main.mark_color = i->main.mark_color;
o->main.default_color = i->main.default_color;
o->main.comment_color = i->main.comment_color;
o->main.keyword_color = i->main.keyword_color;
o->main.str_constant_color = i->main.str_constant_color;
o->main.char_constant_color = i->main.char_constant_color;
o->main.int_constant_color = i->main.int_constant_color;
o->main.float_constant_color = i->main.float_constant_color;
o->main.bool_constant_color = i->main.bool_constant_color;
o->main.include_color = i->main.include_color;
o->main.preproc_color = i->main.preproc_color;
o->main.special_character_color = i->main.special_character_color;
o->main.highlight_junk_color = i->main.highlight_junk_color;
o->main.highlight_white_color = i->main.highlight_white_color;
o->main.paste_color = i->main.paste_color;
o->main.undo_color = i->main.paste_color ^ 0x00FFFFFF;
o->main.next_undo_color = i->main.paste_color ^ 0x00FFFFFF;
o->main.file_info_style = i->main.file_info_style;
o->main.file_info_style.bar_active_color = i->main.file_info_style.bar_color;
}
inline u32*
style_index_by_tag(Style *s, u32 tag){
u32 *result = 0;
switch (tag){
case STAG_BAR_COLOR: result = &s->main.file_info_style.bar_color; break;
case STAG_BAR_ACTIVE_COLOR: result = &s->main.file_info_style.bar_active_color; break;
case STAG_BAR_BASE_COLOR: result = &s->main.file_info_style.base_color; break;
case STAG_BAR_POP1_COLOR: result = &s->main.file_info_style.pop1_color; break;
case STAG_BAR_POP2_COLOR: result = &s->main.file_info_style.pop2_color; break;
case STAG_BACK_COLOR: result = &s->main.back_color; break;
case STAG_MARGIN_COLOR: result = &s->main.margin_color; break;
case STAG_MARGIN_HOVER_COLOR: result = &s->main.margin_hover_color; break;
case STAG_MARGIN_ACTIVE_COLOR: result = &s->main.margin_active_color; break;
case STAG_CURSOR_COLOR: result = &s->main.cursor_color; break;
case STAG_AT_CURSOR_COLOR: result = &s->main.at_cursor_color; break;
case STAG_HIGHLIGHT_COLOR: result = &s->main.highlight_color; break;
case STAG_AT_HIGHLIGHT_COLOR: result = &s->main.at_highlight_color; break;
case STAG_MARK_COLOR: result = &s->main.mark_color; break;
case STAG_DEFAULT_COLOR: result = &s->main.default_color; break;
case STAG_COMMENT_COLOR: result = &s->main.comment_color; break;
case STAG_KEYWORD_COLOR: result = &s->main.keyword_color; break;
case STAG_STR_CONSTANT_COLOR: result = &s->main.str_constant_color; break;
case STAG_CHAR_CONSTANT_COLOR: result = &s->main.char_constant_color; break;
case STAG_INT_CONSTANT_COLOR: result = &s->main.int_constant_color; break;
case STAG_FLOAT_CONSTANT_COLOR: result = &s->main.float_constant_color; break;
case STAG_BOOL_CONSTANT_COLOR: result = &s->main.bool_constant_color; break;
case STAG_PREPROC_COLOR: result = &s->main.preproc_color; break;
case STAG_INCLUDE_COLOR: result = &s->main.include_color; break;
case STAG_SPECIAL_CHARACTER_COLOR: result = &s->main.special_character_color; break;
case STAG_HIGHLIGHT_JUNK_COLOR: result = &s->main.highlight_junk_color; break;
case STAG_HIGHLIGHT_WHITE_COLOR: result = &s->main.highlight_white_color; break;
case STAG_PASTE_COLOR: result = &s->main.paste_color; break;
case STAG_UNDO_COLOR: result = &s->main.undo_color; break;
case STAG_NEXT_UNDO_COLOR: result = &s->main.next_undo_color; break;
}
return result;
}
internal Style_File_Format*
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format *style){
out->name = make_string(out->name_, 0, ArrayCount(out->name_) - 1);
out->name_[ArrayCount(out->name_) - 1] = 0;
copy(&out->name, style->name);
out->font = font_set_extract(fonts, style->font_name, style->font_name_size);
i32 spec_count = style->color_specifier_count;
Style_Color_Specifier *spec = (Style_Color_Specifier*)(style + 1);
for (i32 i = 0; i < spec_count; ++i, ++spec){
u32 *color = style_index_by_tag(out, spec->tag);
if (color) *color = spec->color;
}
#if 0 // TODO(allen): when new colors are introduced, derive them here.
for (u32 i = 0; i < STAG_COUNT; ++i){
u32 *color = style_index_by_tag(out, i);
if (color && (*color >> 24) == 0){
switch (i){
}
}
}
#endif
return (Style_File_Format*)(spec);
}
inline void
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v4 *style){
out->name = make_string(out->name_, 0, ArrayCount(out->name_) - 1);
out->name_[ArrayCount(out->name_) - 1] = 0;
copy(&out->name, style->name);
out->font = font_set_extract(fonts, style->font_name, style->font_name_size);
out->main = style->main;
}
inline void
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v1 *style){
Style_File_Format_v2 form2;
Style_File_Format form;
Style_File_Format_v3 form3;
Style_File_Format_v4 form;
style_form_convert(&form2, style);
style_form_convert(&form, &form2);
style_form_convert(&form3, &form2);
style_form_convert(&form, &form3);
style_format_for_use(fonts, out, &form);
}
inline void
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v2 *style){
Style_File_Format form;
Style_File_Format_v3 form3;
Style_File_Format_v4 form;
style_form_convert(&form3, style);
style_form_convert(&form, &form3);
style_format_for_use(fonts, out, &form);
}
inline void
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v3 *style){
Style_File_Format_v4 form;
style_form_convert(&form, style);
style_format_for_use(fonts, out, &form);
}
@ -304,6 +508,7 @@ style_library_import(u8 *filename, Font_Set *fonts, Style *out, i32 max,
style_format_for_use(fonts, out++, in++);
}
}break;
case 3:
{
Style_File_Format_v3 *in = (Style_File_Format_v3*)cursor;
@ -311,6 +516,14 @@ style_library_import(u8 *filename, Font_Set *fonts, Style *out, i32 max,
style_format_for_use(fonts, out++, in++);
}
}break;
case 4:
{
Style_File_Format *in = (Style_File_Format*)cursor;
for (i32 i = 0; i < to_read; ++i){
in = style_format_for_use(fonts, out++, in);
}
}break;
default: result = 0; break;
}
@ -345,21 +558,34 @@ style_library_add(Style_Library *library, Style *style){
return result;
}
internal Style_File_Format
style_format_for_file(Style *style){
Style_File_Format result;
internal Style_File_Format*
style_format_for_file(Style *style, Style_File_Format *out){
Font *font = style->font;
result.name_size = style->name.size;
memcpy(result.name, style->name.str, ArrayCount(result.name));
result.font_name_size = font->name.size;
memcpy(result.font_name, font->name.str, ArrayCount(result.font_name));
result.main = style->main;
return result;
out->name_size = style->name.size;
memcpy(out->name, style->name.str, ArrayCount(out->name));
out->font_name_size = font->name.size;
memcpy(out->font_name, font->name.str, ArrayCount(out->font_name));
Style_Color_Specifier *spec = (Style_Color_Specifier*)(out + 1);
i32 count = 0;
for (u32 i = 0; i < STAG_COUNT; ++i){
u32 *color = style_index_by_tag(style, i);
if (color){
spec->tag = i;
spec->color = *color;
++count;
++spec;
}
}
out->color_specifier_count = count;
return (Style_File_Format*)spec;
}
internal void
style_library_export(u8 *filename, Style **styles, i32 count){
i32 size = count*sizeof(Style_File_Format) +
i32 size = count*(sizeof(Style_File_Format) + STAG_COUNT*sizeof(Style_Color_Specifier)) +
sizeof(P4C_Page_Header) + sizeof(Style_Page_Header);
void *data = system_get_memory(size);
void *cursor = data;
@ -373,7 +599,7 @@ style_library_export(u8 *filename, Style **styles, i32 count){
{
Style_Page_Header *h = (Style_Page_Header*)cursor;
h->version = 1;
h->version = 4;
h->count = count;
cursor = h+1;
}
@ -381,7 +607,7 @@ style_library_export(u8 *filename, Style **styles, i32 count){
Style_File_Format *out = (Style_File_Format*)cursor;
Style **in = styles;
for (i32 i = 0; i < count; ++i){
*out++ = style_format_for_file(*in++);
out = style_format_for_file(*in++, out);
}
system_save_file(filename, data, size);
system_free_memory(data);