Skip to content

Commit c4e4793

Browse files
author
Allen Webster
committed
Undo fade out
1 parent 33933da commit c4e4793

15 files changed

+175
-35
lines changed

4ed_api_implementation.cpp

+20-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ function void
1313
output_file_append(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 value){
1414
i64 end = buffer_size(&file->state.buffer);
1515
Edit_Behaviors behaviors = {};
16+
behaviors.pos_before_edit = end;
1617
edit_single(tctx, models, file, Ii64(end), value, behaviors);
1718
}
1819

@@ -237,6 +238,22 @@ buffer_read_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range,
237238
return(result);
238239
}
239240

241+
function Edit_Behaviors
242+
get_active_edit_behaviors(Models *models, Editing_File *file){
243+
Panel *panel = layout_get_active_panel(&models->layout);
244+
Assert(panel != 0);
245+
View *view = panel->view;
246+
Assert(view != 0);
247+
Edit_Behaviors behaviors = {};
248+
if (view->file == file){
249+
behaviors.pos_before_edit = view->edit_pos_.cursor_pos;
250+
}
251+
else{
252+
behaviors.pos_before_edit = -1;
253+
}
254+
return(behaviors);
255+
}
256+
240257
api(custom) function b32
241258
buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, String_Const_u8 string)
242259
{
@@ -246,7 +263,7 @@ buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 rang
246263
if (api_check_buffer(file)){
247264
i64 size = buffer_size(&file->state.buffer);
248265
if (0 <= range.first && range.first <= range.one_past_last && range.one_past_last <= size){
249-
Edit_Behaviors behaviors = {};
266+
Edit_Behaviors behaviors = get_active_edit_behaviors(models, file);
250267
edit_single(app->tctx, models, file, range, string, behaviors);
251268
result = true;
252269
}
@@ -261,7 +278,7 @@ buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, Batch_Edit *batch
261278
Editing_File *file = imp_get_file(models, buffer_id);
262279
b32 result = false;
263280
if (api_check_buffer(file)){
264-
Edit_Behaviors behaviors = {};
281+
Edit_Behaviors behaviors = get_active_edit_behaviors(models, file);
265282
result = edit_batch(app->tctx, models, file, batch, behaviors);
266283
}
267284
return(result);
@@ -2422,6 +2439,7 @@ buffer_history_get_max_record_index(Application_Links *app, Buffer_ID buffer_id)
24222439
function void
24232440
buffer_history__fill_record_info(Record *record, Record_Info *out){
24242441
out->kind = record->kind;
2442+
out->pos_before_edit = record->pos_before_edit;
24252443
out->edit_number = record->edit_number;
24262444
switch (out->kind){
24272445
case RecordKind_Single:

4ed_edit.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ edit__apply(Thread_Context *tctx, Models *models, Editing_File *file, Range_i64
239239
if (!behaviors.do_not_post_to_history){
240240
ProfileTLBlock(tctx, &models->profile_list, "edit apply history");
241241
history_record_edit(&models->global_history, &file->state.history, buffer,
242-
edit);
242+
behaviors.pos_before_edit, edit);
243243
file->state.current_record_index =
244244
history_get_record_count(&file->state.history);
245245
}
@@ -348,6 +348,7 @@ edit_change_current_history_state(Thread_Context *tctx, Models *models, Editing_
348348

349349
Edit_Behaviors behaviors_prototype = {};
350350
behaviors_prototype.do_not_post_to_history = true;
351+
behaviors_prototype.pos_before_edit = -1;
351352

352353
if (current < target_index){
353354
do{

4ed_edit.h

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
struct Edit_Behaviors{
1616
b32 do_not_post_to_history;
17+
i64 pos_before_edit;
1718
};
1819

1920
#endif

4ed_history.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -241,14 +241,22 @@ history__free_nodes(History *history, i32 first_index, Node *first_node, Node *l
241241
}
242242

243243
internal void
244-
history_record_edit(Global_History *global_history, History *history, Gap_Buffer *buffer, Edit edit){
244+
history_record_edit(Global_History *global_history, History *history, Gap_Buffer *buffer,
245+
i64 pos_before_edit, Edit edit){
245246
if (history->activated){
246247
Assert(history->record_lookup.count == history->record_count);
247248

248249
Record *new_record = history__allocate_record(history);
249250
history__stash_record(history, new_record);
250251

251252
new_record->restore_point = begin_temp(&history->arena);
253+
if (pos_before_edit >= 0){
254+
new_record->pos_before_edit = pos_before_edit;
255+
}
256+
else{
257+
new_record->pos_before_edit = edit.range.min;
258+
}
259+
252260
new_record->edit_number = global_history_get_edit_number(global_history);
253261

254262
new_record->kind = RecordKind_Single;
@@ -294,6 +302,7 @@ history__optimize_group(Arena *scratch, History *history, Record *record){
294302
if (record->group.count == 1){
295303
Record *child = right;
296304
record->restore_point = child->restore_point;
305+
record->pos_before_edit = child->pos_before_edit;
297306
record->edit_number = child->edit_number;
298307
record->kind = RecordKind_Single;
299308
record->single = child->single;
@@ -383,6 +392,7 @@ history_merge_records(Arena *scratch, History *history, i32 first_index, i32 las
383392
Record *last_record = CastFromMember(Record, node, last_node);
384393

385394
new_record->restore_point = first_record->restore_point;
395+
new_record->pos_before_edit = first_record->pos_before_edit;
386396
new_record->edit_number = last_record->edit_number;
387397
new_record->kind = RecordKind_Group;
388398

4ed_history.h

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct Record_Batch_Slot{
2121
struct Record{
2222
Node node;
2323
Temp_Memory restore_point;
24+
i64 pos_before_edit;
2425
i32 edit_number;
2526
Record_Kind kind;
2627
union{

4ed_view.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,16 @@ struct View{
7979
f32 preferred_x;
8080

8181
b8 new_scroll_target;
82+
b8 hide_scrollbar;
83+
b8 hide_file_bar;
84+
b8 show_whitespace;
8285

8386
Coroutine *co;
8487
Co_Out co_out;
8588

8689
Arena node_arena;
8790
View_Context_Node *ctx;
8891

89-
b8 hide_scrollbar;
90-
b8 hide_file_bar;
91-
b8 show_whitespace;
92-
9392
Query_Set query_set;
9493
};
9594

custom/4coder_base_commands.cpp

+73-12
Original file line numberDiff line numberDiff line change
@@ -1700,9 +1700,10 @@ CUSTOM_DOC("Reopen the current buffer from the hard drive.")
17001700

17011701
////////////////////////////////
17021702

1703-
internal i32
1703+
internal i64
17041704
record_get_new_cursor_position_undo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index, Record_Info record){
1705-
i32 new_edit_position = 0;
1705+
i64 new_edit_position = record.pos_before_edit;
1706+
#if 0
17061707
switch (record.kind){
17071708
default:
17081709
case RecordKind_Single:
@@ -1715,16 +1716,17 @@ record_get_new_cursor_position_undo(Application_Links *app, Buffer_ID buffer_id,
17151716
new_edit_position = (i32)(sub_record.single_first + sub_record.single_string_backward.size);
17161717
}break;
17171718
}
1719+
#endif
17181720
return(new_edit_position);
17191721
}
17201722

1721-
internal i32
1723+
internal i64
17221724
record_get_new_cursor_position_undo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index){
17231725
Record_Info record = buffer_history_get_record_info(app, buffer_id, index);
17241726
return(record_get_new_cursor_position_undo(app, buffer_id, index, record));
17251727
}
17261728

1727-
internal i32
1729+
internal i64
17281730
record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index, Record_Info record){
17291731
i64 new_edit_position = 0;
17301732
switch (record.kind){
@@ -1742,21 +1744,80 @@ record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id,
17421744
return((i32)(new_edit_position));
17431745
}
17441746

1745-
internal i32
1747+
internal i64
17461748
record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index){
17471749
Record_Info record = buffer_history_get_record_info(app, buffer_id, index);
17481750
return(record_get_new_cursor_position_redo(app, buffer_id, index, record));
17491751
}
17501752

1753+
function void
1754+
undo__fade_finish(Application_Links *app, Fade_Range *range){
1755+
Buffer_ID buffer = range->buffer_id;
1756+
History_Record_Index current = buffer_history_get_current_state_index(app, buffer);
1757+
if (current > 0){
1758+
buffer_history_set_current_state_index(app, buffer, current - 1);
1759+
}
1760+
}
1761+
1762+
function void
1763+
undo__flush_fades(Application_Links *app, Buffer_ID buffer){
1764+
Fade_Range **prev_next = &buffer_fade_ranges.first;
1765+
for (Fade_Range *node = buffer_fade_ranges.first, *next = 0;
1766+
node != 0;
1767+
node = next){
1768+
next = node->next;
1769+
if (node->buffer_id == buffer &&
1770+
node->finish_call == undo__fade_finish){
1771+
undo__fade_finish(app, node);
1772+
*prev_next = next;
1773+
free_fade_range(node);
1774+
buffer_fade_ranges.count -= 1;
1775+
}
1776+
else{
1777+
prev_next = &node->next;
1778+
buffer_fade_ranges.last = node;
1779+
}
1780+
}
1781+
}
1782+
17511783
CUSTOM_COMMAND_SIG(undo)
17521784
CUSTOM_DOC("Advances backwards through the undo history of the current buffer.")
17531785
{
17541786
View_ID view = get_active_view(app, Access_ReadWriteVisible);
17551787
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
1788+
undo__flush_fades(app, buffer);
1789+
17561790
History_Record_Index current = buffer_history_get_current_state_index(app, buffer);
17571791
if (current > 0){
1758-
i32 new_position = record_get_new_cursor_position_undo(app, buffer, current);
1759-
buffer_history_set_current_state_index(app, buffer, current - 1);
1792+
Record_Info record = buffer_history_get_record_info(app, buffer, current);
1793+
1794+
b32 do_immedite_undo = true;
1795+
f32 undo_fade_time = 0.33f;
1796+
if (undo_fade_time > 0.f &&
1797+
record.kind == RecordKind_Single &&
1798+
record.single_string_backward.size == 0){
1799+
b32 has_hard_character = false;
1800+
for (u64 i = 0; i < record.single_string_forward.size; i += 1){
1801+
if (!character_is_whitespace(record.single_string_forward.str[i])){
1802+
has_hard_character = true;
1803+
break;
1804+
}
1805+
}
1806+
if (has_hard_character){
1807+
Range_i64 range = Ii64_size(record.single_first, record.single_string_forward.size);
1808+
ARGB_Color color = fcolor_resolve(fcolor_id(defcolor_undo)) & 0xFFFFFF;
1809+
Fade_Range *fade = buffer_post_fade(app, buffer, undo_fade_time, range, color);
1810+
fade->negate_fade_direction = true;
1811+
fade->finish_call = undo__fade_finish;
1812+
do_immedite_undo = false;
1813+
}
1814+
}
1815+
1816+
if (do_immedite_undo){
1817+
buffer_history_set_current_state_index(app, buffer, current - 1);
1818+
}
1819+
1820+
i64 new_position = record_get_new_cursor_position_undo(app, buffer, current, record);
17601821
view_set_cursor_and_preferred_x(app, view, seek_pos(new_position));
17611822
}
17621823
}
@@ -1769,7 +1830,7 @@ CUSTOM_DOC("Advances forwards through the undo history of the current buffer.")
17691830
History_Record_Index current = buffer_history_get_current_state_index(app, buffer);
17701831
History_Record_Index max_index = buffer_history_get_max_record_index(app, buffer);
17711832
if (current < max_index){
1772-
i32 new_position = record_get_new_cursor_position_redo(app, buffer, current + 1);
1833+
i64 new_position = record_get_new_cursor_position_redo(app, buffer, current + 1);
17731834
buffer_history_set_current_state_index(app, buffer, current + 1);
17741835
view_set_cursor_and_preferred_x(app, view, seek_pos(new_position));
17751836
}
@@ -1806,15 +1867,15 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
18061867
}
18071868

18081869
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
1809-
i32 *new_positions = push_array(scratch, i32, match_count);
1870+
i64 *new_positions = push_array(scratch, i64, match_count);
18101871
match_count = 0;
18111872

18121873
if (highest_edit_number != -1){
18131874
for (Buffer_ID buffer = first_buffer_match;
18141875
buffer != 0;
18151876
buffer = get_buffer_next(app, buffer, Access_Always)){
18161877
b32 did_match = false;
1817-
i32 new_edit_position = 0;
1878+
i64 new_edit_position = 0;
18181879
for (;;){
18191880
History_Record_Index index = buffer_history_get_current_state_index(app, buffer);
18201881
if (index > 0){
@@ -1879,15 +1940,15 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
18791940
}
18801941

18811942
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
1882-
i32 *new_positions = push_array(scratch, i32, match_count);
1943+
i64 *new_positions = push_array(scratch, i64, match_count);
18831944
match_count = 0;
18841945

18851946
if (lowest_edit_number != -1){
18861947
for (Buffer_ID buffer = first_buffer_match;
18871948
buffer != 0;
18881949
buffer = get_buffer_next(app, buffer, Access_Always)){
18891950
b32 did_match = false;
1890-
i32 new_edit_position = 0;
1951+
i64 new_edit_position = 0;
18911952
History_Record_Index max_index = buffer_history_get_max_record_index(app, buffer);
18921953
for (;;){
18931954
History_Record_Index index = buffer_history_get_current_state_index(app, buffer);

custom/4coder_base_types.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -2894,6 +2894,23 @@ SCu32(u32 *str){
28942894
return(string);
28952895
}
28962896

2897+
function String_Const_char
2898+
SCchar(String_char string){
2899+
return(string.string);
2900+
}
2901+
function String_Const_u8
2902+
SCu8(String_u8 string){
2903+
return(string.string);
2904+
}
2905+
function String_Const_u16
2906+
SCu16(String_u16 string){
2907+
return(string.string);
2908+
}
2909+
function String_Const_u32
2910+
SCu32(String_u32 string){
2911+
return(string.string);
2912+
}
2913+
28972914
function String_Const_char
28982915
SCchar(String_Const_u8 str){
28992916
return(SCchar((char*)str.str, str.size));
@@ -5332,6 +5349,11 @@ string_any_push(Arena *arena, u64 size, String_Encoding encoding){
53325349
return(string);
53335350
}
53345351

5352+
#define push_string_u8 string_u8_push
5353+
#define push_string_u16 string_u16_push
5354+
#define push_string_u32 string_u32_push
5355+
#define push_string_u64 string_u64_push
5356+
53355357
function String_Const_char
53365358
string_const_char_push(Arena *arena, u64 size){
53375359
String_Const_char string = {};
@@ -5373,6 +5395,11 @@ string_const_any_push(Arena *arena, u64 size, String_Encoding encoding){
53735395
return(string);
53745396
}
53755397

5398+
#define push_string_const_u8 string_const_u8_push
5399+
#define push_string_const_u16 string_const_u16_push
5400+
#define push_string_const_u32 string_const_u32_push
5401+
#define push_string_const_u64 string_const_u64_push
5402+
53765403
function String_Const_char
53775404
push_string_copy(Arena *arena, String_Const_char src){
53785405
String_Const_char string = {};
@@ -5641,6 +5668,11 @@ string_list_push_overlap(Arena *arena, List_String_Const_u32 *list, u32 overlap,
56415668
}
56425669
}
56435670

5671+
#define push_string_list string_list_push
5672+
#define push_string_list_lit(a,l,s) string_list_push_lit(a,l,s)
5673+
#define push_string_list_u8_lit(a,l,s) string_list_u8_push_lit(a,l,s)
5674+
#define push_string_list_overlap(a,l,o,s) string_list_push_overlap(a,l,o,s)
5675+
56445676
typedef String_Const_char String_char_Mod_Function_Type(String_Const_char string);
56455677
typedef String_Const_u8 String_u8_Mod_Function_Type(String_Const_u8 string);
56465678
typedef String_Const_u16 String_u16_Mod_Function_Type(String_Const_u16 string);

0 commit comments

Comments
 (0)