diff --git a/4coder_API.html b/4coder_API.html index ba20221f..6a5d6085 100644 --- a/4coder_API.html +++ b/4coder_API.html @@ -92,6 +92,7 @@ Coming Soon
  • Buffer_Setting_ID
  • View_Setting_ID
  • Mouse_Cursor_Show_Type
  • +
  • Buffer_Seek_Type
  • Key_Modifier_Flag
  • Buffer_Create_Flag
  • Buffer_Kill_Flag
  • @@ -108,6 +109,9 @@ Coming Soon
  • File_Info
  • File_List
  • Buffer_Identifier
  • +
  • GUI_Scroll_Vars
  • +
  • Full_Cursor
  • +
  • Buffer_Seek
  • Buffer_Summary
  • View_Summary
  • User_Input
  • @@ -1228,8 +1232,28 @@ the range [1,16].

    The MouseCursorShow_Never mode always shows the cursor.

    +
    +

    §3.4.13: Buffer_Seek_Type

    +
    enum Buffer_Seek_Type;
    +
    Description
    UNDOCUMENTED.
    Values
    +
    buffer_seek_pos
    +
    UNDOCUMENTED.
    +
    +
    +
    buffer_seek_wrapped_xy
    +
    UNDOCUMENTED.
    +
    +
    +
    buffer_seek_unwrapped_xy
    +
    UNDOCUMENTED.
    +
    +
    +
    buffer_seek_line_char
    +
    UNDOCUMENTED.
    +
    +

    -

    §3.4.13: Key_Modifier_Flag

    +

    §3.4.14: Key_Modifier_Flag

    enum Key_Modifier_Flag;
    Description
    A Key_Modifier_Flag field is used to specify a specific state of modifiers. Flags can be combined with bit or to specify a state with multiple modifiers.
    Flags
    @@ -1250,7 +1274,7 @@ Flags can be combined with bit or to specify a state with multiple modifiers.

    -

    §3.4.14: Buffer_Create_Flag

    +

    §3.4.15: Buffer_Create_Flag

    enum Buffer_Create_Flag;
    Description
    A Buffer_Create_Flag field specifies how a buffer should be created.
    Flags
    BufferCreate_Background = 0x1
    @@ -1263,7 +1287,7 @@ Flags can be combined with bit or to specify a state with multiple modifiers.

    -

    §3.4.15: Buffer_Kill_Flag

    +

    §3.4.16: Buffer_Kill_Flag

    enum Buffer_Kill_Flag;
    Description
    A Buffer_Kill_Flag field specifies how a buffer should be killed.
    Flags
    BufferKill_Background = 0x1
    @@ -1276,7 +1300,7 @@ Flags can be combined with bit or to specify a state with multiple modifiers.

    -

    §3.4.16: Access_Flag

    +

    §3.4.17: Access_Flag

    enum Access_Flag;
    Description
    An Access_Flag field specifies what sort of permission you grant to an access call. An access call is usually one the returns a summary struct. If a @@ -1306,7 +1330,7 @@ that protection flag, the object is still returned from the access call.

    -

    §3.4.17: Seek_Boundary_Flag

    +

    §3.4.18: Seek_Boundary_Flag

    enum Seek_Boundary_Flag;
    Description
    A Seek_Boundary_Flag field specifies a set of "boundary" types used in seeks for the beginning or end of different types of words.
    Flags
    @@ -1327,7 +1351,7 @@ beginning or end of different types of words.
    -

    §3.4.18: Command_Line_Input_Flag

    +

    §3.4.19: Command_Line_Input_Flag

    enum Command_Line_Input_Flag;
    Description
    A Command_Line_Input_Flag field specifies the behavior of a call to a command line interface.
    Flags
    CLI_OverlapWithConflict = 0x1
    @@ -1348,7 +1372,7 @@ beginning or end of different types of words.
    -

    §3.4.19: Auto_Indent_Flag

    +

    §3.4.20: Auto_Indent_Flag

    enum Auto_Indent_Flag;
    Description
    An Auto_Indent_Flag field specifies the behavior of an auto indentation operation.
    Flags
    AutoIndent_ClearLine = 0x1
    @@ -1364,7 +1388,7 @@ beginning or end of different types of words.
    -

    §3.4.20: Set_Buffer_Flag

    +

    §3.4.21: Set_Buffer_Flag

    enum Set_Buffer_Flag;
    Description
    A Set_Buffer_Flag field specifies the behavior of an operation that sets the buffer of a view.
    Flags
    SetBuffer_KeepOriginalGUI = 0x1
    @@ -1374,7 +1398,7 @@ beginning or end of different types of words.
    -

    §3.4.21: Input_Type_Flag

    +

    §3.4.22: Input_Type_Flag

    enum Input_Type_Flag;
    Description
    A Input_Type_Flag field specifies a set of input event types.
    Flags
    EventOnAnyKey = 0x1
    @@ -1414,7 +1438,7 @@ beginning or end of different types of words.
    -

    §3.4.22: Generic_Command

    +

    §3.4.23: Generic_Command

    union Generic_Command {
    Command_ID cmdid;
    @@ -1435,7 +1459,7 @@ internal command or a custom command.
    -

    §3.4.23: Key_Event_Data

    +

    §3.4.24: Key_Event_Data

    struct Key_Event_Data {
    Key_Code keycode;
    @@ -1469,7 +1493,7 @@ at the time of the event.
    -

    §3.4.24: Mouse_State

    +

    §3.4.25: Mouse_State

    struct Mouse_State {
    char l;
    @@ -1529,7 +1553,7 @@ mouse if in the window.
    -

    §3.4.25: Range

    +

    §3.4.26: Range

    union Range {
    struct {
    @@ -1569,7 +1593,7 @@ Throughout the API ranges are thought of in the form [min,max
    -

    §3.4.26: File_Info

    +

    §3.4.27: File_Info

    struct File_Info {
    char * filename;
    @@ -1592,7 +1616,7 @@ int folder;
    See Also

    -

    §3.4.27: File_List

    +

    §3.4.28: File_List

    struct File_List {
    void * block;
    @@ -1620,7 +1644,7 @@ int block_size;

    -

    §3.4.28: Buffer_Identifier

    +

    §3.4.29: Buffer_Identifier

    struct Buffer_Identifier {
    char * name;
    @@ -1644,8 +1668,153 @@ can either be a name or an id. If the
    This field is the id of the buffer. If name is specified this should be 0.

    +
    +

    §3.4.30: GUI_Scroll_Vars

    +
    struct GUI_Scroll_Vars {
    +
    +float scroll_y;
    +int32_t target_y;
    +int32_t prev_target_y;
    +int32_t max_y;
    +float scroll_x;
    +int32_t target_x;
    +int32_t prev_target_x;
    +
    +};
    +
    +
    Description
    This struct is a part of an incomplete feature.
    Fields
    +
    scroll_y
    +
    TODO
    +
    +
    +
    target_y
    +
    TODO
    +
    +
    +
    prev_target_y
    +
    TODO
    +
    +
    +
    max_y
    +
    TODO
    +
    +
    +
    scroll_x
    +
    TODO
    +
    +
    +
    target_x
    +
    TODO
    +
    +
    +
    prev_target_x
    +
    TODO
    +
    +

    +
    +

    §3.4.31: Full_Cursor

    +
    struct Full_Cursor {
    +
    +int32_t pos;
    +int32_t line;
    +int32_t character;
    +float unwrapped_x;
    +float unwrapped_y;
    +float wrapped_x;
    +float wrapped_y;
    +
    +};
    +
    +
    Description
    UNDOCUMENTED.
    Fields
    +
    pos
    +
    UNDOCUMENTED.
    +
    +
    +
    line
    +
    UNDOCUMENTED.
    +
    +
    +
    character
    +
    UNDOCUMENTED.
    +
    +
    +
    unwrapped_x
    +
    UNDOCUMENTED.
    +
    +
    +
    unwrapped_y
    +
    UNDOCUMENTED.
    +
    +
    +
    wrapped_x
    +
    UNDOCUMENTED.
    +
    +
    +
    wrapped_y
    +
    UNDOCUMENTED.
    +
    +

    +
    +

    §3.4.32: Buffer_Seek

    +
    struct Buffer_Seek {
    +
    +Buffer_Seek_Type type;
    +union {
    +
    +struct {
    +
    +int32_t pos;
    +
    +};
    +struct {
    +
    +bool32 round_down;
    +float x;
    +float y;
    +
    +};
    +struct {
    +
    +int32_t line;
    +int32_t character;
    +
    +};
    +
    +};
    +
    +};
    +
    +
    Description
    UNDOCUMENTED.
    Fields
    +
    type
    +
    UNDOCUMENTED.
    +
    +
    +
    pos
    +
    UNDOCUMENTED.
    +
    +
    +
    round_down
    +
    UNDOCUMENTED.
    +
    +
    +
    x
    +
    UNDOCUMENTED.
    +
    +
    +
    y
    +
    UNDOCUMENTED.
    +
    +
    +
    line
    +
    UNDOCUMENTED.
    +
    +
    +
    character
    +
    UNDOCUMENTED.
    +
    +

    -

    §3.4.29: Buffer_Summary

    +

    §3.4.33: Buffer_Summary

    struct Buffer_Summary {
    bool32 exists;
    @@ -1710,7 +1879,7 @@ int32_t map_id;

    -

    §3.4.30: View_Summary

    +

    §3.4.34: View_Summary

    struct View_Summary {
    bool32 exists;
    @@ -1780,7 +1949,7 @@ GUI_Scroll_Vars scroll_vars;

    -

    §3.4.31: User_Input

    +

    §3.4.35: User_Input

    struct User_Input {
    User_Input_Type_ID type;
    @@ -1817,7 +1986,7 @@ Generic_Command command;
    See Also

    -

    §3.4.32: Query_Bar

    +

    §3.4.36: Query_Bar

    struct Query_Bar {
    String prompt;
    @@ -1836,7 +2005,7 @@ that will be displayed as a drop down bar durring an interactive command.
    <

    -

    §3.4.33: Event_Message

    +

    §3.4.37: Event_Message

    struct Event_Message {
    int type;
    @@ -1849,7 +2018,7 @@ int type;

    -

    §3.4.34: Theme_Color

    +

    §3.4.38: Theme_Color

    struct Theme_Color {
    Style_Tag tag;
    diff --git a/4coder_buffer_types.h b/4coder_buffer_types.h index 3ca46096..77eed529 100644 --- a/4coder_buffer_types.h +++ b/4coder_buffer_types.h @@ -12,29 +12,6 @@ #ifndef FRED_BUFFER_TYPES_H #define FRED_BUFFER_TYPES_H -typedef struct Full_Cursor{ - int pos; - int line, character; - float unwrapped_x, unwrapped_y; - float wrapped_x, wrapped_y; -} Full_Cursor; - -typedef enum Buffer_Seek_Type{ - buffer_seek_pos, - buffer_seek_wrapped_xy, - buffer_seek_unwrapped_xy, - buffer_seek_line_char -} Buffer_Seek_Type; - -typedef struct Buffer_Seek{ - Buffer_Seek_Type type; - union{ - struct { int pos; }; - struct { int round_down; float x, y; }; - struct { int line, character; }; - }; -} Buffer_Seek; - static Buffer_Seek seek_pos(int pos){ Buffer_Seek result; diff --git a/4coder_custom.h b/4coder_custom.h index a6f140d3..0be5cf89 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -9,8 +9,6 @@ #include "4coder_style.h" #include "4coder_rect.h" #include "4coder_mem.h" -#include "4coder_buffer_types.h" -#include "4coder_gui.h" #ifndef FRED_STRING_STRUCT #define FRED_STRING_STRUCT @@ -51,6 +49,8 @@ enum Special_Hook_ID{ typedef CUSTOM_COMMAND_SIG(Custom_Command_Function); #include "4coder_types.h" +#include "4coder_buffer_types.h" +#include "4coder_gui.h" #define COMMAND_CALLER_HOOK(name) int name(struct Application_Links *app, Generic_Command cmd) typedef COMMAND_CALLER_HOOK(Command_Caller_Hook_Function); diff --git a/4coder_gui.h b/4coder_gui.h index 6e1a272a..4a1c378e 100644 --- a/4coder_gui.h +++ b/4coder_gui.h @@ -13,17 +13,6 @@ gui_id_zero(){ return(id); } -struct GUI_Scroll_Vars{ - float scroll_y; - int target_y; - int prev_target_y; - int max_y; - - float scroll_x; - int target_x; - int prev_target_x; -}; - typedef struct GUI GUI; #define GUI_BEGIN_SIG(n) void n(GUI *gui) @@ -40,19 +29,17 @@ typedef struct GUI GUI; #define GUI_FILE_SIG(n) void n(GUI *gui, int buffer_id) -extern "C"{ - typedef GUI_BEGIN_SIG(GUI_Begin_Function); - typedef GUI_END_SIG(GUI_End_Function); - - typedef GUI_TOP_BAR_SIG(GUI_Top_Bar_Function); - - typedef GUI_GET_SCROLL_VARS_SIG(GUI_Get_Scroll_Vars_Function); - - typedef GUI_BEGIN_SCROLLABLE_SIG(GUI_Begin_Scrollable_Function); - typedef GUI_END_SCROLLABLE_SIG(GUI_End_Scrollable_Function); - - typedef GUI_FILE_SIG(GUI_File_Function); -} +typedef GUI_BEGIN_SIG(GUI_Begin_Function); +typedef GUI_END_SIG(GUI_End_Function); + +typedef GUI_TOP_BAR_SIG(GUI_Top_Bar_Function); + +typedef GUI_GET_SCROLL_VARS_SIG(GUI_Get_Scroll_Vars_Function); + +typedef GUI_BEGIN_SCROLLABLE_SIG(GUI_Begin_Scrollable_Function); +typedef GUI_END_SCROLLABLE_SIG(GUI_End_Scrollable_Function); + +typedef GUI_FILE_SIG(GUI_File_Function); struct GUI_Functions{ GUI_Begin_Function *begin; diff --git a/4coder_types.h b/4coder_types.h index b680e8eb..a1773271 100644 --- a/4coder_types.h +++ b/4coder_types.h @@ -286,6 +286,18 @@ ENUM(int32_t, Mouse_Cursor_Show_Type){ // MouseCursorShow_WhenActive,// TODO(allen): coming soon }; +/* DOC(UNDOCUMENTED.) */ +ENUM(int32_t, Buffer_Seek_Type){ + /* DOC(UNDOCUMENTED.) */ + buffer_seek_pos, + /* DOC(UNDOCUMENTED.) */ + buffer_seek_wrapped_xy, + /* DOC(UNDOCUMENTED.) */ + buffer_seek_unwrapped_xy, + /* DOC(UNDOCUMENTED.) */ + buffer_seek_line_char +}; + /* DOC( Generic_Command acts as a name for a command, and can name an internal command or a custom command. @@ -426,6 +438,69 @@ struct Buffer_Identifier{ int id; }; +/* DOC(This struct is a part of an incomplete feature.) */ +struct GUI_Scroll_Vars{ + /* DOC(TODO) */ + float scroll_y; + /* DOC(TODO) */ + int32_t target_y; + /* DOC(TODO) */ + int32_t prev_target_y; + /* DOC(TODO) */ + int32_t max_y; + + /* DOC(TODO) */ + float scroll_x; + /* DOC(TODO) */ + int32_t target_x; + /* DOC(TODO) */ + int32_t prev_target_x; +}; + +/* DOC(UNDOCUMENTED.) */ +struct Full_Cursor{ + /* DOC(UNDOCUMENTED.) */ + int32_t pos; + /* DOC(UNDOCUMENTED.) */ + int32_t line; + /* DOC(UNDOCUMENTED.) */ + int32_t character; + /* DOC(UNDOCUMENTED.) */ + float unwrapped_x; + /* DOC(UNDOCUMENTED.) */ + float unwrapped_y; + /* DOC(UNDOCUMENTED.) */ + float wrapped_x; + /* DOC(UNDOCUMENTED.) */ + float wrapped_y; +}; + +/* DOC(UNDOCUMENTED.) */ +struct Buffer_Seek{ + /* DOC(UNDOCUMENTED.) */ + Buffer_Seek_Type type; + union{ + struct { + /* DOC(UNDOCUMENTED.) */ + int32_t pos; + }; + struct { + /* DOC(UNDOCUMENTED.) */ + bool32 round_down; + /* DOC(UNDOCUMENTED.) */ + float x; + /* DOC(UNDOCUMENTED.) */ + float y; + }; + struct { + /* DOC(UNDOCUMENTED.) */ + int32_t line; + /* DOC(UNDOCUMENTED.) */ + int32_t character; + }; + }; +}; + /* DOC( Buffer_Summary acts as a handle to a buffer and describes the state of the buffer. ) */ @@ -467,9 +542,7 @@ struct Buffer_Summary{ int32_t map_id; }; -/* DOC( -View_Summary acts as a handle to a view and describes the state of the view. -) */ +/* DOC(View_Summary acts as a handle to a view and describes the state of the view.) */ struct View_Summary{ /* DOC( This field indicates whether the View_Summary describes a view that is open in 4coder. @@ -563,4 +636,3 @@ struct Theme_Color{ int_color color; }; - diff --git a/4ed.cpp b/4ed.cpp index 6b43db58..8153dc99 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -318,34 +318,31 @@ COMMAND_DECL(center_view){ REQ_READABLE_VIEW(view); REQ_FILE(file, view); - f32 y = 0, h = 0; + Assert(view->edit_pos); + + f32 h = view_file_height(view); + f32 y = view->edit_pos->cursor.wrapped_y; if (view->file_data.unwrapped_lines){ - y = view->edit_poss.cursor.unwrapped_y; - } - else{ - y = view->edit_poss.cursor.wrapped_y; + y = view->edit_pos->cursor.unwrapped_y; } - h = view_file_height(view); y = clamp_bottom(0.f, y - h*.5f); - - view->edit_poss.scroll.target_y = ROUND32(y); + view->edit_pos->scroll.target_y = ROUND32(y); } COMMAND_DECL(left_adjust_view){ REQ_READABLE_VIEW(view); REQ_FILE(file, view); - f32 x = 0; + Assert(view->edit_pos); + + f32 x = view->edit_pos->cursor.wrapped_x; if (view->file_data.unwrapped_lines){ - x = view->edit_poss.cursor.unwrapped_x; - } - else{ - x = view->edit_poss.cursor.wrapped_x; + x = view->edit_pos->cursor.unwrapped_x; } x = clamp_bottom(0.f, x - 30.f); - view->edit_poss.scroll.target_x = ROUND32(x); + view->edit_pos->scroll.target_x = ROUND32(x); } COMMAND_DECL(word_complete){ @@ -354,6 +351,8 @@ COMMAND_DECL(word_complete){ REQ_OPEN_VIEW(view); REQ_FILE(file, view); + Assert(view->edit_pos); + Partition *part = &models->mem.part; General_Memory *general = &models->mem.general; Working_Set *working_set = &models->working_set; @@ -381,7 +380,7 @@ COMMAND_DECL(word_complete){ } if (do_init){ - word_end = view->edit_poss.cursor.pos; + word_end = view->edit_pos->cursor.pos; word_start = word_end; cursor_pos = word_end - 1; @@ -642,18 +641,20 @@ COMMAND_DECL(toggle_line_wrap){ REQ_READABLE_VIEW(view); REQ_FILE(file, view); + Assert(view->edit_pos); + // TODO(allen): WHAT TO DO HERE??? Relative_Scrolling scrolling = view_get_relative_scrolling(view); if (view->file_data.unwrapped_lines){ view->file_data.unwrapped_lines = 0; file->settings.unwrapped_lines = 0; - view->edit_poss.scroll.target_x = 0; - view_cursor_move(view, view->edit_poss.cursor.pos); + view->edit_pos->scroll.target_x = 0; + view_cursor_move(view, view->edit_pos->cursor.pos); } else{ view->file_data.unwrapped_lines = 1; file->settings.unwrapped_lines = 1; - view_cursor_move(view, view->edit_poss.cursor.pos); + view_cursor_move(view, view->edit_pos->cursor.pos); } view_set_relative_scrolling(view, scrolling); } @@ -683,7 +684,7 @@ case_change_range(System_Functions *system, Mem_Options *mem, View *view, Editing_File *file, u8 a, u8 z, u8 char_delta){ #if BUFFER_EXPERIMENT_SCALPEL <= 0 - Range range = make_range(view->edit_poss.cursor.pos, view->edit_poss.mark); + Range range = make_range(view->edit_pos->cursor.pos, view->edit_pos->mark); if (range.start < range.end){ Edit_Step step = {}; step.type = ED_NORMAL; @@ -893,25 +894,27 @@ COMMAND_DECL(close_panel){ COMMAND_DECL(page_down){ REQ_READABLE_VIEW(view); + Assert(view->edit_pos); + i32 height = CEIL32(view_file_height(view)); f32 y = view_get_cursor_y(view); - f32 x = view->edit_poss.preferred_x; + f32 x = view->edit_pos->preferred_x; - Full_Cursor cursor = - view_compute_cursor_from_xy(view, x, y+height); - edit_pos_set_cursor(&view->edit_poss, cursor, false, view->file_data.unwrapped_lines); + Full_Cursor cursor = view_compute_cursor_from_xy(view, x, y+height); + view_set_cursor(view, cursor, false, view->file_data.unwrapped_lines); } COMMAND_DECL(page_up){ REQ_READABLE_VIEW(view); + Assert(view->edit_pos); + i32 height = CEIL32(view_file_height(view)); f32 y = view_get_cursor_y(view); - f32 x = view->edit_poss.preferred_x; + f32 x = view->edit_pos->preferred_x; - Full_Cursor cursor = - view_compute_cursor_from_xy(view, x, y-height); - edit_pos_set_cursor(&view->edit_poss, cursor, false, view->file_data.unwrapped_lines); + Full_Cursor cursor = view_compute_cursor_from_xy(view, x, y-height); + view_set_cursor(view, cursor, false, view->file_data.unwrapped_lines); } COMMAND_DECL(open_color_tweaker){ @@ -1124,7 +1127,7 @@ app_hardcode_styles(Models *models){ file_info_style.bar_color = 0xFF888888; file_info_style.bar_active_color = 0xFF666666; file_info_style.base_color = 0xFF000000; - file_info_style.pop1_color = 0xFF1050F0; + file_info_style.pop1_color = 0xFF3C57DC; file_info_style.pop2_color = 0xFFFF0000; style->main.file_info_style = file_info_style; ++style; @@ -2533,9 +2536,17 @@ App_Step_Sig(app_step){ summary.mouse = mouse_state; } - GUI_Scroll_Vars *scroll_vars = &view->edit_poss.scroll; - if (view->showing_ui != VUI_None){ - scroll_vars = &view->gui_scroll; + b32 file_scroll = false; + GUI_Scroll_Vars scroll_zero = {0}; + GUI_Scroll_Vars *scroll_vars = &view->gui_scroll; + if (view->showing_ui == VUI_None){ + if (view->file_data.file){ + scroll_vars = &view->edit_pos->scroll; + file_scroll = true; + } + else{ + scroll_vars = &scroll_zero; + } } Input_Process_Result ip_result = @@ -2554,8 +2565,8 @@ App_Step_Sig(app_step){ } if (!gui_scroll_eq(scroll_vars, &ip_result.vars)){ - if (scroll_vars == &view->edit_poss.scroll){ - edit_pos_set_scroll(&view->edit_poss, ip_result.vars); + if (file_scroll){ + view_set_scroll(view, ip_result.vars); } else{ *scroll_vars = ip_result.vars; @@ -2927,9 +2938,17 @@ App_Step_Sig(app_step){ draw_push_clip(target, panel->inner); - GUI_Scroll_Vars *scroll_vars = &view->edit_poss.scroll; - if (view->showing_ui != VUI_None){ - scroll_vars = &view->gui_scroll; + b32 file_scroll = false; + GUI_Scroll_Vars scroll_zero = {0}; + GUI_Scroll_Vars *scroll_vars = &view->gui_scroll; + if (view->showing_ui == VUI_None){ + if (view->file_data.file){ + scroll_vars = &view->edit_pos->scroll; + file_scroll = true; + } + else{ + scroll_vars = &scroll_zero; + } } do_render_file_view(system, view, scroll_vars, cmd->view, diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 8163b314..d7b6450a 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -66,12 +66,12 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_ view->buffer_id = buffer_id; - view->mark = view_compute_cursor_from_pos(vptr, vptr->edit_poss.mark); - view->cursor = vptr->edit_poss.cursor; - view->preferred_x = vptr->edit_poss.preferred_x; + view->mark = view_compute_cursor_from_pos(vptr, vptr->edit_pos->mark); + view->cursor = vptr->edit_pos->cursor; + view->preferred_x = vptr->edit_pos->preferred_x; view->file_region = vptr->file_region; - view->scroll_vars = vptr->edit_poss.scroll; + view->scroll_vars = vptr->edit_pos->scroll; } } } @@ -1236,8 +1236,8 @@ DOC_SEE(Buffer_Seek) seek.character = 1; } Full_Cursor cursor = view_compute_cursor(vptr, seek); - edit_pos_set_cursor(&vptr->edit_poss, cursor, - set_preferred_x, vptr->file_data.unwrapped_lines); + view_set_cursor(vptr, cursor, + set_preferred_x, vptr->file_data.unwrapped_lines); fill_view_summary(view, vptr, cmd); } } @@ -1255,19 +1255,23 @@ DOC_SEE(Buffer_Seek) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; View *vptr = imp_get_view(cmd, view); + Editing_File *file = 0; Full_Cursor cursor = {0}; bool32 result = false; if (vptr){ - result = true; - if (seek.type != buffer_seek_pos){ - cursor = view_compute_cursor(vptr, seek); - vptr->edit_poss.mark = cursor.pos; + file = vptr->file_data.file; + if (file && !file->is_loading){ + result = true; + if (seek.type != buffer_seek_pos){ + cursor = view_compute_cursor(vptr, seek); + vptr->edit_pos->mark = cursor.pos; + } + else{ + vptr->edit_pos->mark = seek.pos; + } + fill_view_summary(view, vptr, cmd); } - else{ - vptr->edit_poss.mark = seek.pos; - } - fill_view_summary(view, vptr, cmd); } return(result); diff --git a/4ed_file.cpp b/4ed_file.cpp index 36f8db48..c5b9eb05 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -27,6 +27,26 @@ #include "buffer/4coder_buffer_abstract.cpp" +enum Edit_Pos_Set_Type{ + EditPos_None, + EditPos_CursorSet, + EditPos_ScrollSet +}; +struct File_Edit_Positions{ + GUI_Scroll_Vars scroll; + Full_Cursor cursor; + i32 mark; + f32 preferred_x; + i32 scroll_i; + i32 last_set_type; + b32 in_view; +}; +inline File_Edit_Positions +file_edit_positions_zero(){ + File_Edit_Positions data = {0}; + return(data); +} + enum Edit_Type{ ED_NORMAL, ED_REVERSE_NORMAL, @@ -126,6 +146,10 @@ struct Editing_File_State{ u64 last_4ed_write_time; u64 last_4ed_edit_time; u64 last_sys_write_time; + + File_Edit_Positions edit_pos_space[16]; + File_Edit_Positions *edit_poss[16]; + i32 edit_poss_count; }; struct Editing_File_Name{ @@ -230,6 +254,133 @@ tbl_file_compare(void *a, void *b, void *arg){ return(result); } +// +// File_Edit_Positions stuff +// + +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; +} + +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); +} + +// +// Working_Set stuff +// + internal void working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16 number_of_files){ Buffer_Slot_ID id; @@ -625,5 +776,7 @@ file_set_to_loading(Editing_File *file){ file->is_loading = 1; } + + // BOTTOM diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 956fcc8b..0da5eb89 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -162,26 +162,6 @@ file_viewing_data_zero(){ return(data); } -enum Edit_Pos_Set_Type{ - EditPos_None, - EditPos_CursorSet, - EditPos_ScrollSet -}; -struct File_Edit_Positions{ - GUI_Scroll_Vars scroll; - Full_Cursor cursor; - i32 mark; - f32 preferred_x; - i32 scroll_i; - - i32 last_set_type; -}; -inline File_Edit_Positions -file_edit_positions_zero(){ - File_Edit_Positions data = {0}; - return(data); -} - struct Scroll_Context{ Editing_File *file; GUI_id scroll; @@ -231,16 +211,11 @@ struct View{ File_Viewing_Data file_data; -#if 0 - i32 prev_cursor_pos; - Scroll_Context prev_context; -#endif - i32_Rect file_region_prev; i32_Rect file_region; i32_Rect scroll_region; - File_Edit_Positions edit_poss; + File_Edit_Positions *edit_pos; View_UI showing_ui; GUI_Target gui_target; @@ -295,6 +270,328 @@ get_view_size(){ return(sizeof(View) - sizeof(View_Persistent)); } +// TODO(allen): Switch over to using an i32 instead of +// an f32 for these. +inline f32 +view_file_width(View *view){ + i32_Rect file_rect = view->file_region; + f32 result = (f32)(file_rect.x1 - file_rect.x0); + return (result); +} + +inline f32 +view_file_height(View *view){ + i32_Rect file_rect = view->file_region; + f32 result = (f32)(file_rect.y1 - file_rect.y0); + return (result); +} + +inline i32 +view_get_cursor_pos(View *view){ + i32 result = 0; + if (view->file_data.show_temp_highlight){ + result = view->file_data.temp_highlight.pos; + } + else if (view->edit_pos){ + result = view->edit_pos->cursor.pos; + } + return(result); +} + +inline f32 +view_get_cursor_x(View *view){ + f32 result = 0; + + Full_Cursor *cursor = 0; + if (view->file_data.show_temp_highlight){ + cursor = &view->file_data.temp_highlight; + } + else if (view->edit_pos){ + cursor = &view->edit_pos->cursor; + } + + if (cursor){ + result = cursor->wrapped_x; + if (view->file_data.unwrapped_lines){ + result = cursor->unwrapped_x; + } + } + + return(result); +} + +inline f32 +view_get_cursor_y(View *view){ + f32 result = 0; + + Full_Cursor *cursor = 0; + if (view->file_data.show_temp_highlight){ + cursor = &view->file_data.temp_highlight; + } + else if (view->edit_pos){ + cursor = &view->edit_pos->cursor; + } + + if (cursor){ + result = cursor->wrapped_y; + if (view->file_data.unwrapped_lines){ + result = cursor->unwrapped_y; + } + } + + return(result); +} + +struct Cursor_Limits{ + f32 min, max; + f32 delta; +}; + +inline Cursor_Limits +view_cursor_limits(View *view){ + Cursor_Limits limits = {0}; + + f32 line_height = (f32)view->line_height; + f32 visible_height = view_file_height(view); + + limits.max = visible_height - line_height*3.f; + limits.min = line_height * 2; + + if (limits.max - limits.min <= line_height){ + if (visible_height >= line_height){ + limits.max = visible_height - line_height; + limits.min = -line_height; + } + else{ + limits.max = visible_height; + limits.min = -line_height; + } + } + + limits.max = (limits.max > 0)?(limits.max):(0); + limits.min = (limits.min > 0)?(limits.min):(0); + + limits.delta = clamp_top(line_height*3.f, (limits.max - limits.min)*.5f); + + return(limits); +} + +inline Full_Cursor +view_compute_cursor_from_pos(View *view, i32 pos){ + Editing_File *file = view->file_data.file; + Models *models = view->persistent.models; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; + + Full_Cursor result = {}; + if (font){ + f32 max_width = view_file_width(view); + result = buffer_cursor_from_pos(&file->state.buffer, pos, view->file_data.line_wrap_y, + max_width, (f32)view->line_height, font->advance_data); + } + return result; +} + +inline Full_Cursor +view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){ + Editing_File *file = view->file_data.file; + Models *models = view->persistent.models; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; + + Full_Cursor result = {}; + if (font){ + f32 max_width = view_file_width(view); + result = buffer_cursor_from_unwrapped_xy(&file->state.buffer, seek_x, seek_y, + round_down, view->file_data.line_wrap_y, max_width, (f32)view->line_height, font->advance_data); + } + + return result; +} + +internal Full_Cursor +view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){ + Editing_File *file = view->file_data.file; + Models *models = view->persistent.models; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; + + Full_Cursor result = {}; + if (font){ + f32 max_width = view_file_width(view); + result = buffer_cursor_from_wrapped_xy(&file->state.buffer, seek_x, seek_y, + round_down, view->file_data.line_wrap_y, + max_width, (f32)view->line_height, font->advance_data); + } + + return (result); +} + +internal Full_Cursor +view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){ + Editing_File *file = view->file_data.file; + Models *models = view->persistent.models; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; + + Full_Cursor result = {}; + if (font){ + f32 max_width = view_file_width(view); + result = buffer_cursor_from_line_character(&file->state.buffer, line, pos, + view->file_data.line_wrap_y, max_width, (f32)view->line_height, font->advance_data); + } + + return (result); +} + +inline Full_Cursor +view_compute_cursor(View *view, Buffer_Seek seek){ + Full_Cursor result = {}; + + switch(seek.type){ + case buffer_seek_pos: + result = view_compute_cursor_from_pos(view, seek.pos); + break; + + case buffer_seek_wrapped_xy: + result = view_compute_cursor_from_wrapped_xy(view, seek.x, seek.y, seek.round_down); + break; + + case buffer_seek_unwrapped_xy: + result = view_compute_cursor_from_unwrapped_xy(view, seek.x, seek.y, seek.round_down); + break; + + case buffer_seek_line_char: + result = view_compute_cursor_from_line_pos(view, seek.line, seek.character); + break; + } + + return (result); +} + +inline Full_Cursor +view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){ + Full_Cursor result; + if (view->file_data.unwrapped_lines) result = view_compute_cursor_from_unwrapped_xy(view, seek_x, seek_y); + else result = view_compute_cursor_from_wrapped_xy(view, seek_x, seek_y); + return result; +} + +internal b32 +view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll, b32 center_view){ + b32 result = false; + f32 max_x = view_file_width(view); + + f32 cursor_y = view_get_cursor_y(view); + f32 cursor_x = view_get_cursor_x(view); + + GUI_Scroll_Vars scroll_vars = *scroll; + i32 target_y = scroll_vars.target_y; + i32 target_x = scroll_vars.target_x; + + Cursor_Limits limits = view_cursor_limits(view); + + if (cursor_y > target_y + limits.max){ + if (center_view){ + target_y = ROUND32(cursor_y - limits.max*.5f); + } + else{ + target_y = CEIL32(cursor_y - limits.max + limits.delta); + } + } + if (cursor_y < target_y + limits.min){ + if (center_view){ + target_y = ROUND32(cursor_y - limits.max*.5f); + } + else{ + target_y = FLOOR32(cursor_y - limits.delta - limits.min); + } + } + + target_y = clamp(0, target_y, scroll_vars.max_y); + + if (cursor_x >= target_x + max_x){ + target_x = CEIL32(cursor_x - max_x/2); + } + else if (cursor_x < target_x){ + target_x = FLOOR32(Max(0, cursor_x - max_x/2)); + } + + if (target_x != scroll_vars.target_x || target_y != scroll_vars.target_y){ + scroll->target_x = target_x; + scroll->target_y = target_y; + result = true; + } + + return(result); +} + +internal b32 +view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll, + Full_Cursor *cursor, f32 preferred_x){ + b32 result = false; + + if (view->edit_pos){ + i32 line_height = view->line_height; + f32 old_cursor_y = cursor->wrapped_y; + if (view->file_data.unwrapped_lines){ + old_cursor_y = cursor->unwrapped_y; + } + f32 cursor_y = old_cursor_y; + f32 target_y = scroll.target_y + view->widget_height; + + Cursor_Limits limits = view_cursor_limits(view); + + if (cursor_y > target_y + limits.max){ + cursor_y = target_y + limits.max; + } + if (target_y != 0 && cursor_y < target_y + limits.min){ + cursor_y = target_y + limits.min; + } + + if (cursor_y != old_cursor_y){ + if (cursor_y > old_cursor_y){ + cursor_y += line_height; + } + else{ + cursor_y -= line_height; + } + + *cursor = view_compute_cursor_from_xy( + view, preferred_x, cursor_y); + + result = true; + } + } + + return(result); +} + +internal void +view_set_cursor(View *view, + Full_Cursor cursor, + b32 set_preferred_x, + b32 unwrapped_lines){ + if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){ + edit_pos_set_cursor_(view->edit_pos, cursor, set_preferred_x, unwrapped_lines); + + GUI_Scroll_Vars scroll = view->edit_pos->scroll; + if (view_move_view_to_cursor(view, &scroll, false)){ + view->edit_pos->scroll = scroll; + } + } +} + +internal void +view_set_scroll(View *view, + GUI_Scroll_Vars scroll){ + if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){ + edit_pos_set_scroll_(view->edit_pos, scroll); + + Full_Cursor cursor = view->edit_pos->cursor; + if (view_move_cursor_to_view(view, view->edit_pos->scroll, + &cursor, view->edit_pos->preferred_x)){ + view->edit_pos->cursor = cursor; + } + } +} + struct View_And_ID{ View *view; i32 id; @@ -339,22 +636,6 @@ view_lock_level(View *view){ return(result); } -// TODO(allen): Switch over to using an i32 instead of -// an f32 for these. -inline f32 -view_file_width(View *view){ - i32_Rect file_rect = view->file_region; - f32 result = (f32)(file_rect.x1 - file_rect.x0); - return (result); -} - -inline f32 -view_file_height(View *view){ - i32_Rect file_rect = view->file_region; - f32 result = (f32)(file_rect.y1 - file_rect.y0); - return (result); -} - struct View_Iter{ View *view; @@ -572,12 +853,12 @@ file_grow_starts_widths_as_needed(General_Memory *general, Buffer_Type *buffer, max = LargeRoundUp(target_lines + max, Kbytes(1)); f32 *new_widths = (f32*)general_memory_reallocate( - general, buffer->line_widths, - sizeof(f32)*count, sizeof(f32)*max, BUBBLE_WIDTHS); + general, buffer->line_widths, + sizeof(f32)*count, sizeof(f32)*max, BUBBLE_WIDTHS); i32 *new_lines = (i32*)general_memory_reallocate( - general, buffer->line_starts, - sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS); + general, buffer->line_starts, + sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS); if (new_lines){ buffer->line_starts = new_lines; @@ -622,7 +903,7 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general, { i32 *new_lines = (i32*)general_memory_reallocate( - general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS); + general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS); // TODO(allen): when unable to grow? TentativeAssert(new_lines); @@ -1391,104 +1672,7 @@ file_post_history(General_Memory *general, Editing_File *file, *result = inv_step; } - return result; -} - -inline Full_Cursor -view_compute_cursor_from_pos(View *view, i32 pos){ - Editing_File *file = view->file_data.file; - Models *models = view->persistent.models; - Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; - - Full_Cursor result = {}; - if (font){ - f32 max_width = view_file_width(view); - result = buffer_cursor_from_pos(&file->state.buffer, pos, view->file_data.line_wrap_y, - max_width, (f32)view->line_height, font->advance_data); - } - return result; -} - -inline Full_Cursor -view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){ - Editing_File *file = view->file_data.file; - Models *models = view->persistent.models; - Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; - - Full_Cursor result = {}; - if (font){ - f32 max_width = view_file_width(view); - result = buffer_cursor_from_unwrapped_xy(&file->state.buffer, seek_x, seek_y, - round_down, view->file_data.line_wrap_y, max_width, (f32)view->line_height, font->advance_data); - } - - return result; -} - -internal Full_Cursor -view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){ - Editing_File *file = view->file_data.file; - Models *models = view->persistent.models; - Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; - - Full_Cursor result = {}; - if (font){ - f32 max_width = view_file_width(view); - result = buffer_cursor_from_wrapped_xy(&file->state.buffer, seek_x, seek_y, - round_down, view->file_data.line_wrap_y, - max_width, (f32)view->line_height, font->advance_data); - } - - return (result); -} - -internal Full_Cursor -view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){ - Editing_File *file = view->file_data.file; - Models *models = view->persistent.models; - Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; - - Full_Cursor result = {}; - if (font){ - f32 max_width = view_file_width(view); - result = buffer_cursor_from_line_character(&file->state.buffer, line, pos, - view->file_data.line_wrap_y, max_width, (f32)view->line_height, font->advance_data); - } - - return (result); -} - -inline Full_Cursor -view_compute_cursor(View *view, Buffer_Seek seek){ - Full_Cursor result = {}; - - switch(seek.type){ - case buffer_seek_pos: - result = view_compute_cursor_from_pos(view, seek.pos); - break; - - case buffer_seek_wrapped_xy: - result = view_compute_cursor_from_wrapped_xy(view, seek.x, seek.y, seek.round_down); - break; - - case buffer_seek_unwrapped_xy: - result = view_compute_cursor_from_unwrapped_xy(view, seek.x, seek.y, seek.round_down); - break; - - case buffer_seek_line_char: - result = view_compute_cursor_from_line_pos(view, seek.line, seek.character); - break; - } - - return (result); -} - -inline Full_Cursor -view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){ - Full_Cursor result; - if (view->file_data.unwrapped_lines) result = view_compute_cursor_from_unwrapped_xy(view, seek_x, seek_y); - else result = view_compute_cursor_from_wrapped_xy(view, seek_x, seek_y); - return result; + return(result); } inline void @@ -1498,184 +1682,6 @@ view_set_temp_highlight(View *view, i32 pos, i32 end_pos){ view->file_data.show_temp_highlight = 1; } -internal void -edit_pos_set_cursor(File_Edit_Positions *edit_poss, - Full_Cursor cursor, - b32 set_preferred_x, - b32 unwrapped_lines){ - edit_poss->cursor = cursor; - if (set_preferred_x){ - edit_poss->preferred_x = cursor.wrapped_x; - if (unwrapped_lines){ - edit_poss->preferred_x = cursor.unwrapped_x; - } - } - edit_poss->last_set_type = EditPos_CursorSet; -} - -internal void -edit_pos_set_scroll(File_Edit_Positions *edit_poss, - GUI_Scroll_Vars scroll){ - edit_poss->scroll = scroll; - edit_poss->last_set_type = EditPos_ScrollSet; -} - -inline i32 -view_get_cursor_pos(View *view){ - i32 result; - if (view->file_data.show_temp_highlight){ - result = view->file_data.temp_highlight.pos; - } - else{ - result = view->edit_poss.cursor.pos; - } - return result; -} - -inline f32 -view_get_cursor_x(View *view){ - f32 result = 0; - - Full_Cursor *cursor = &view->edit_poss.cursor; - if (view->file_data.show_temp_highlight){ - cursor = &view->file_data.temp_highlight; - } - - result = cursor->wrapped_y; - if (view->file_data.unwrapped_lines){ - result = cursor->unwrapped_x; - } - - return result; -} - -inline f32 -view_get_cursor_y(View *view){ - f32 result = 0; - - Full_Cursor *cursor = &view->edit_poss.cursor; - if (view->file_data.show_temp_highlight){ - cursor = &view->file_data.temp_highlight; - } - - result = cursor->wrapped_y; - if (view->file_data.unwrapped_lines){ - result = cursor->unwrapped_y; - } - - return result; -} - -struct Cursor_Limits{ - f32 min, max; - f32 delta; -}; - -inline Cursor_Limits -view_cursor_limits(View *view){ - Cursor_Limits limits = {0}; - - f32 line_height = (f32)view->line_height; - f32 visible_height = view_file_height(view); - - limits.max = visible_height - line_height*3.f; - limits.min = line_height * 2; - - if (limits.max - limits.min <= line_height){ - if (visible_height >= line_height){ - limits.max = visible_height - line_height; - limits.min = -line_height; - } - else{ - limits.max = visible_height; - limits.min = -line_height; - } - } - - limits.max = (limits.max > 0)?(limits.max):(0); - limits.min = (limits.min > 0)?(limits.min):(0); - - limits.delta = clamp_top(line_height*3.f, (limits.max - limits.min)*.5f); - - return(limits); -} - -internal void -view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll){ - i32 line_height = view->line_height; - f32 old_cursor_y = view_get_cursor_y(view); - f32 cursor_y = old_cursor_y; - f32 target_y = scroll.target_y + view->widget_height; - - Cursor_Limits limits = view_cursor_limits(view); - - if (cursor_y > target_y + limits.max){ - cursor_y = target_y + limits.max; - } - if (target_y != 0 && cursor_y < target_y + limits.min){ - cursor_y = target_y + limits.min; - } - - if (cursor_y != old_cursor_y){ - if (cursor_y > old_cursor_y){ - cursor_y += line_height; - } - else{ - cursor_y -= line_height; - } - - Full_Cursor new_cursor = - view_compute_cursor_from_xy(view, view->edit_poss.preferred_x, cursor_y); - edit_pos_set_cursor(&view->edit_poss, new_cursor, - false, view->file_data.unwrapped_lines); - } -} - -internal void -view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll, b32 center_view){ - f32 max_x = view_file_width(view); - - f32 cursor_y = view_get_cursor_y(view); - f32 cursor_x = view_get_cursor_x(view); - - GUI_Scroll_Vars scroll_vars = *scroll; - i32 target_y = scroll_vars.target_y; - i32 target_x = scroll_vars.target_x; - - Cursor_Limits limits = view_cursor_limits(view); - - if (cursor_y > target_y + limits.max){ - if (center_view){ - target_y = ROUND32(cursor_y - limits.max*.5f); - } - else{ - target_y = CEIL32(cursor_y - limits.max + limits.delta); - } - } - if (cursor_y < target_y + limits.min){ - if (center_view){ - target_y = ROUND32(cursor_y - limits.max*.5f); - } - else{ - target_y = FLOOR32(cursor_y - limits.delta - limits.min); - } - } - - target_y = clamp(0, target_y, scroll_vars.max_y); - - if (cursor_x >= target_x + max_x){ - target_x = CEIL32(cursor_x - max_x/2); - } - else if (cursor_x < target_x){ - target_x = FLOOR32(Max(0, cursor_x - max_x/2)); - } - - if (target_x != scroll_vars.target_x || target_y != scroll_vars.target_y){ - scroll->target_x = target_x; - scroll->target_y = target_y; - } -} - inline void file_view_nullify_file(View *view){ General_Memory *general = &view->persistent.models->mem.general; @@ -1691,26 +1697,34 @@ view_set_file(View *view, Editing_File *file, Models *models){ touch_file(&models->working_set, view->file_data.file); } + File_Edit_Positions *edit_pos = view->edit_pos; + + if (edit_pos){ + edit_pos_unset(view->file_data.file, edit_pos); + edit_pos = 0; + } + file_view_nullify_file(view); view->file_data.file = file; if (file){ view->file_data.unwrapped_lines = file->settings.unwrapped_lines; - // TODO(allen): Here is where the fancy logic goes for - // File_Edit_Positions stuff. - - File_Edit_Positions *edit_poss = &view->edit_poss; - *edit_poss = file_edit_positions_zero(); + edit_pos = edit_pos_get_new(file, view->persistent.id); + view->edit_pos = edit_pos; if (file_is_ready(file)){ view_measure_wraps(&models->mem.general, view); - edit_poss->cursor = view_compute_cursor_from_pos(view, 0); - edit_poss->scroll.max_y = view_compute_max_target_y(view); - edit_poss->preferred_x = view_get_cursor_x(view); - view_move_view_to_cursor(view, &edit_poss->scroll, true); +#if 0 + edit_pos->cursor = view_compute_cursor_from_pos(view, 0); + edit_pos->scroll.max_y = view_compute_max_target_y(view); + edit_pos->preferred_x = view_get_cursor_x(view); + + view_move_view_to_cursor(view, &edit_pos->scroll, true); view->reinit_scrolling = 1; +#endif + } } } @@ -1722,26 +1736,30 @@ struct Relative_Scrolling{ internal Relative_Scrolling view_get_relative_scrolling(View *view){ - Relative_Scrolling result; - f32 cursor_y = view_get_cursor_y(view); - result.scroll_y = cursor_y - view->edit_poss.scroll.scroll_y; - result.target_y = cursor_y - view->edit_poss.scroll.target_y; + Relative_Scrolling result = {0}; + if (view->edit_pos){ + f32 cursor_y = view_get_cursor_y(view); + result.scroll_y = cursor_y - view->edit_pos->scroll.scroll_y; + result.target_y = cursor_y - view->edit_pos->scroll.target_y; + } return(result); } internal void view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){ f32 cursor_y = view_get_cursor_y(view); - - view->edit_poss.scroll.scroll_y = cursor_y - scrolling.scroll_y; - view->edit_poss.scroll.target_y = - ROUND32(clamp_bottom(0.f, cursor_y - scrolling.target_y)); + + if (view->edit_pos){ + view->edit_pos->scroll.scroll_y = cursor_y - scrolling.scroll_y; + view->edit_pos->scroll.target_y = + ROUND32(clamp_bottom(0.f, cursor_y - scrolling.target_y)); + } } inline void view_cursor_move(View *view, Full_Cursor cursor){ - edit_pos_set_cursor(&view->edit_poss, cursor, - true, view->file_data.unwrapped_lines); + view_set_cursor(view, cursor, + true, view->file_data.unwrapped_lines); view->file_data.show_temp_highlight = 0; } @@ -1992,9 +2010,10 @@ file_edit_cursor_fix(System_Functions *system, view = panel->view; if (view->file_data.file == file){ view_measure_wraps(general, view); - write_cursor_with_index(cursors, &cursor_count, view->edit_poss.cursor.pos); - write_cursor_with_index(cursors, &cursor_count, view->edit_poss.mark - 1); - write_cursor_with_index(cursors, &cursor_count, view->edit_poss.scroll_i - 1); + Assert(view->edit_pos); + write_cursor_with_index(cursors, &cursor_count, view->edit_pos->cursor.pos); + write_cursor_with_index(cursors, &cursor_count, view->edit_pos->mark - 1); + write_cursor_with_index(cursors, &cursor_count, view->edit_pos->scroll_i - 1); } } @@ -2014,27 +2033,28 @@ file_edit_cursor_fix(System_Functions *system, cursor_count = 0; for (dll_items(panel, used_panels)){ view = panel->view; - if (view && view->file_data.file == file){ + if (view->file_data.file == file){ + Assert(view->edit_pos); view_cursor_move(view, cursors[cursor_count++].pos); - view->edit_poss.mark = cursors[cursor_count++].pos + 1; + view->edit_pos->mark = cursors[cursor_count++].pos + 1; i32 new_scroll_i = cursors[cursor_count++].pos + 1; - if (view->edit_poss.scroll_i != new_scroll_i){ - view->edit_poss.scroll_i = new_scroll_i; - temp_cursor = view_compute_cursor_from_pos(view, view->edit_poss.scroll_i); + if (view->edit_pos->scroll_i != new_scroll_i){ + view->edit_pos->scroll_i = new_scroll_i; + temp_cursor = view_compute_cursor_from_pos(view, view->edit_pos->scroll_i); - f32 y_offset = MOD(view->edit_poss.scroll.scroll_y, view->line_height); + f32 y_offset = MOD(view->edit_pos->scroll.scroll_y, view->line_height); f32 y_position = temp_cursor.wrapped_y; if (view->file_data.unwrapped_lines){ y_position = temp_cursor.unwrapped_y; } y_position += y_offset; - GUI_Scroll_Vars scroll = view->edit_poss.scroll; + GUI_Scroll_Vars scroll = view->edit_pos->scroll; scroll.target_y += ROUND32(y_position - scroll.scroll_y); scroll.scroll_y = y_position; - edit_pos_set_scroll(&view->edit_poss, scroll); + view_set_scroll(view, scroll); } } } @@ -2257,6 +2277,9 @@ view_undo_redo(System_Functions *system, Edit_Stack *stack, Edit_Type expected_type){ Editing_File *file = view->file_data.file; + Assert(file); + Assert(view->edit_pos); + if (stack->edit_count > 0){ Edit_Step step = stack->edits[stack->edit_count-1]; @@ -2272,10 +2295,11 @@ view_undo_redo(System_Functions *system, file_do_single_edit(system, models, file, spec, hist_normal); view_cursor_move(view, step.edit.start + step.edit.len); - view->edit_poss.mark = view->edit_poss.cursor.pos; + view->edit_pos->mark = view->edit_pos->cursor.pos; Style *style = main_style(models); - view_post_paste_effect(view, 0.333f, step.edit.start, step.edit.len, + view_post_paste_effect(view, 0.333f, + step.edit.start, step.edit.len, style->main.undo_color); } else{ @@ -2365,6 +2389,9 @@ view_history_step(System_Functions *system, Models *models, View *view, History_ Editing_File *file = view->file_data.file; + Assert(file); + Assert(view->edit_pos); + b32 do_history_step = 0; Edit_Step step = {}; if (history_mode == hist_backward){ @@ -2404,7 +2431,7 @@ view_history_step(System_Functions *system, Models *models, View *view, History_ view_cursor_move(view, step.edit.start + step.edit.len); break; } - view->edit_poss.mark = view->edit_poss.cursor.pos; + view->edit_pos->mark = view->edit_pos->cursor.pos; } else{ TentativeAssert(spec.step.special_type == 1); @@ -2533,6 +2560,7 @@ view_clean_whitespace(System_Functions *system, Models *models, View *view){ i32 edit_count = 0; Assert(file && !file->is_dummy); + Assert(view->edit_pos); Temp_Memory temp = begin_temp_memory(part); Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max); @@ -2570,7 +2598,7 @@ view_clean_whitespace(System_Functions *system, Models *models, View *view){ char *inv_str = (char*)part->base + part->pos; Edit_Spec spec = file_compute_whitespace_edit(mem, file, - view->edit_poss.cursor.pos, + view->edit_pos->cursor.pos, edits, str_base, str_size, inverse_array, inv_str, part->max - part->pos, edit_count); @@ -3068,11 +3096,14 @@ update_view_line_height(Models *models, View *view){ internal void remeasure_file_view(System_Functions *system, View *view){ if (file_is_ready(view->file_data.file)){ + Assert(view->edit_pos); + Relative_Scrolling relative = view_get_relative_scrolling(view); view_measure_wraps(&view->persistent.models->mem.general, view); if (view->file_data.show_temp_highlight == 0){ - view_cursor_move(view, view->edit_poss.cursor.pos); + view_cursor_move(view, view->edit_pos->cursor.pos); } + view_set_relative_scrolling(view, relative); } } @@ -3128,7 +3159,6 @@ view_show_file(View *view){ if (view->showing_ui != VUI_None){ view->showing_ui = VUI_None; view->changed_context_in_step = true; - view->reinit_scrolling = true; } } @@ -3568,58 +3598,32 @@ view_begin_cursor_scroll_updates(View *view){ internal void view_end_cursor_scroll_updates(View *view){ - i32 set_type = view->edit_poss.last_set_type; - - switch (set_type){ - case EditPos_None: break; - - case EditPos_CursorSet: - { - if (view->gui_target.did_file){ - view->edit_poss.scroll.max_y = view_compute_max_target_y(view); - } - view_move_view_to_cursor(view, &view->edit_poss.scroll, false); - gui_post_scroll_vars(&view->gui_target, &view->edit_poss.scroll, view->scroll_region); - }break; - - case EditPos_ScrollSet: - { - view_move_cursor_to_view(view, view->edit_poss.scroll); - gui_post_scroll_vars(&view->gui_target, &view->edit_poss.scroll, view->scroll_region); - }break; - } #if 0 - switch (cursor_scroll_state){ - case CursorScroll_NoChange:break; + if (view->edit_pos){ + i32 set_type = view->edit_pos->last_set_type; - case CursorScroll_Cursor: - case CursorScroll_Cursor|CursorScroll_Scroll: - if (view->gui_target.did_file){ - view->recent.scroll.max_y = view_compute_max_target_y(view); + switch (set_type){ + case EditPos_None: break; + + case EditPos_CursorSet: + { + if (view->gui_target.did_file){ + view->edit_pos->scroll.max_y = view_compute_max_target_y(view); + } + view_move_view_to_cursor(view, &view->edit_pos->scroll, false); + gui_post_scroll_vars(&view->gui_target, &view->edit_pos->scroll, view->scroll_region); + }break; + + case EditPos_ScrollSet: + { + view_move_cursor_to_view(view, view->edit_pos->scroll); + gui_post_scroll_vars(&view->gui_target, &view->edit_pos->scroll, view->scroll_region); + }break; } - view_move_view_to_cursor(view, view->current_scroll, false); - gui_post_scroll_vars(&view->gui_target, view->current_scroll, view->scroll_region); - break; - - case CursorScroll_Scroll: - view_move_cursor_to_view(view, view->recent.scroll); - gui_post_scroll_vars(&view->gui_target, view->current_scroll, view->scroll_region); - break; } - - if (cursor_scroll_state & CursorScroll_ContextChange){ - view->current_scroll->scroll_y = (f32)view->current_scroll->target_y; - view->current_scroll->scroll_x = (f32)view->current_scroll->target_x; - gui_post_scroll_vars(&view->gui_target, view->current_scroll, view->scroll_region); - } - - view->prev_cursor_pos = view_get_cursor_pos(view); - - view->prev_context.file = view->file_data.file; - view->prev_context.scroll = view->gui_target.scroll_id; - view->prev_context.mode = view->showing_ui; #endif + } internal b32 @@ -4077,13 +4081,20 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su // TODO(allen): ???? #if 0 - gui_get_scroll_vars(target, scroll_context, - &view->recent.scroll, &view->scroll_region); + gui_get_scroll_vars(target, scroll_context, &view->scroll_region); #endif - - gui_begin_scrollable(target, scroll_context, - view->edit_poss.scroll, + + GUI_Scroll_Vars scroll_zero = {0}; + GUI_Scroll_Vars *scroll = &scroll_zero; + + if (view->file_data.file){ + Assert(view->edit_pos); + scroll = &view->edit_pos->scroll; + } + + gui_begin_scrollable(target, scroll_context, *scroll, delta, show_scrollbar); + gui_do_file(target); gui_end_scrollable(target); } @@ -4164,7 +4175,6 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su message = make_lit_string("Theme Library - Click to Select"); gui_do_text_field(target, message, empty_string); - gui_get_scroll_vars(target, scroll_context, &view->scroll_region); gui_begin_scrollable(target, scroll_context, view->gui_scroll, 9 * view->line_height, show_scrollbar); @@ -4237,7 +4247,6 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su view->color_mode = CV_Mode_Library; } - gui_get_scroll_vars(target, scroll_context, &view->scroll_region); gui_begin_scrollable(target, scroll_context, view->gui_scroll, 9 * view->line_height, show_scrollbar); @@ -4353,7 +4362,6 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su GUI_Item_Update update = {0}; Hot_Directory *hdir = &models->hot_directory; b32 do_new_directory = 0; - b32 snap_into_view = 0; i32 i = 0; { @@ -4378,10 +4386,10 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su gui_do_text_field(target, message, hdir->string); + b32 snap_into_view = false; scroll_context.id[0] = (u64)(hdir); - if (gui_get_scroll_vars(target, scroll_context, - &view->scroll_region)){ - snap_into_view = 1; + if (gui_scroll_was_activated(target, scroll_context)){ + snap_into_view = true; } gui_begin_scrollable(target, scroll_context, view->gui_scroll, 9 * view->line_height, show_scrollbar); @@ -4437,7 +4445,6 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su case IInt_Live_File_List: { - b32 snap_into_view = 0; persist String message_unsaved = make_lit_string(" *"); persist String message_unsynced = make_lit_string(" !"); @@ -4470,10 +4477,10 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su gui_do_text_field(target, message, view->dest); + b32 snap_into_view = false; scroll_context.id[0] = (u64)(working_set); - if (gui_get_scroll_vars(target, scroll_context, - &view->scroll_region)){ - snap_into_view = 1; + if (gui_scroll_was_activated(target, scroll_context)){ + snap_into_view = true; } gui_begin_scrollable(target, scroll_context, view->gui_scroll, 9 * view->line_height, show_scrollbar); @@ -4941,20 +4948,22 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su SHOW_GUI_BLANK(0); SHOW_GUI_LINE(1, "file editing positions"); { - File_Edit_Positions *edit_poss = &view_ptr->edit_poss; + File_Edit_Positions *edit_pos = view_ptr->edit_pos; - SHOW_GUI_SCROLL(2, h_align, "scroll:", edit_poss->scroll); - SHOW_GUI_BLANK (2); - SHOW_GUI_CURSOR(2, h_align, "cursor:", edit_poss->cursor); - SHOW_GUI_BLANK (2); - SHOW_GUI_INT (2, h_align, "mark", edit_poss->mark); - SHOW_GUI_FLOAT (2, h_align, "preferred_x", edit_poss->preferred_x); - SHOW_GUI_INT (2, h_align, "scroll_i", edit_poss->scroll_i); + if (edit_pos){ + SHOW_GUI_SCROLL(2, h_align, "scroll:", edit_pos->scroll); + SHOW_GUI_BLANK (2); + SHOW_GUI_CURSOR(2, h_align, "cursor:", edit_pos->cursor); + SHOW_GUI_BLANK (2); + SHOW_GUI_INT (2, h_align, "mark", edit_pos->mark); + SHOW_GUI_FLOAT (2, h_align, "preferred_x", edit_pos->preferred_x); + SHOW_GUI_INT (2, h_align, "scroll_i", edit_pos->scroll_i); + } + else{ + SHOW_GUI_LINE(2, "NULL"); + } } - SHOW_GUI_BLANK (0); - SHOW_GUI_SCROLL(1, h_align, "curent scroll:", view_ptr->edit_poss.scroll); - SHOW_GUI_BLANK (0); SHOW_GUI_SCROLL(1, h_align, "gui scroll:", view_ptr->gui_scroll); @@ -4976,7 +4985,6 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su SHOW_GUI_REGION (2, h_align, "region_original", view_ptr->gui_target.region_original); SHOW_GUI_BLANK (2); -// SHOW_GUI_SCROLL (2, h_align, "scroll_updated", view_ptr->gui_target.scroll_updated); SHOW_GUI_REGION (2, h_align, "region_updated", view_ptr->gui_target.region_updated); @@ -5000,9 +5008,12 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su internal f32 view_get_scroll_y(View *view){ - f32 v; + f32 v = 0; if (view->showing_ui == VUI_None){ - v = view->edit_poss.scroll.scroll_y; + File_Edit_Positions *edit_pos = view->edit_pos; + if (edit_pos){ + v = edit_pos->scroll.scroll_y; + } } else{ v = view->gui_scroll.scroll_y; @@ -5312,6 +5323,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target i32 max_y = rect.y1 - rect.y0 + line_height; Assert(file && !file->is_dummy && buffer_good(&file->state.buffer)); + Assert(view->edit_pos); b32 tokens_use = 0; Cpp_Token_Stack token_stack = {}; @@ -5335,11 +5347,14 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target i32 count = 0; Full_Cursor render_cursor = {0}; - Buffer_Render_Options opts = {}; + Buffer_Render_Options opts = {0}; f32 *wraps = view->file_data.line_wrap_y; - f32 scroll_x = view->edit_poss.scroll.scroll_x; - f32 scroll_y = view->edit_poss.scroll.scroll_y; + f32 scroll_x = 0; + f32 scroll_y = 0; + + scroll_x = view->edit_pos->scroll.scroll_x; + scroll_y = view->edit_pos->scroll.scroll_y; // NOTE(allen): For now we will temporarily adjust scroll_y to try // to prevent the view moving around until floating sections are added @@ -5352,7 +5367,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target (f32)max_x, advance_data, (f32)line_height); - view->edit_poss.scroll_i = render_cursor.pos; + view->edit_pos->scroll_i = render_cursor.pos; buffer_get_render_data(&file->state.buffer, items, max, &count, (f32)rect.x0, (f32)rect.y0, @@ -5374,7 +5389,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target at_cursor_color = style->main.at_highlight_color; } else{ - cursor_begin = view->edit_poss.cursor.pos; + cursor_begin = view->edit_pos->cursor.pos; cursor_end = cursor_begin + 1; cursor_color = style->main.cursor_color; at_cursor_color = style->main.at_cursor_color; @@ -5464,7 +5479,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target char_color = color_blend(char_color, fade_amount, fade_color); - if (ind == view->edit_poss.mark && prev_ind != ind){ + if (ind == view->edit_pos->mark && prev_ind != ind){ draw_rectangle_outline(target, char_rect, mark_color); } if (item->glyphid != 0){ @@ -5582,9 +5597,9 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re char line_number_space[30]; String line_number = make_fixed_width_string(line_number_space); append(&line_number, " L#"); - append_int_to_str(&line_number, view->edit_poss.cursor.line); + append_int_to_str(&line_number, view->edit_pos->cursor.line); append(&line_number, " C#"); - append_int_to_str(&line_number, view->edit_poss.cursor.character); + append_int_to_str(&line_number, view->edit_pos->cursor.character); intbar_draw_string(target, &bar, line_number, base_color); @@ -6203,10 +6218,12 @@ search_next_match(Partition *part, Search_Set *set, Search_Iter *iter_){ inline void view_change_size(General_Memory *general, View *view){ if (view->file_data.file){ + Assert(view->edit_pos); view_measure_wraps(general, view); - Full_Cursor cursor = view_compute_cursor_from_pos(view, view->edit_poss.cursor.pos); - edit_pos_set_cursor(&view->edit_poss, cursor, - false, view->file_data.unwrapped_lines); + Full_Cursor cursor = + view_compute_cursor_from_pos(view, view->edit_pos->cursor.pos); + view_set_cursor(view, cursor, + false, view->file_data.unwrapped_lines); } } diff --git a/4ed_gui.cpp b/4ed_gui.cpp index b5321c73..069be04d 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -653,6 +653,7 @@ gui_scroll_eq(GUI_Scroll_Vars *a, GUI_Scroll_Vars *b){ return(result); } +#if 0 // TODO(allen): Rethink this a little, seems like there are two separate things we want to do here: // Getting the updated scroll vars, and telling the user when scrolling actions occur. internal b32 @@ -668,6 +669,21 @@ gui_get_scroll_vars(GUI_Target *target, GUI_id scroll_context_id, i32_Rect *regi } return(result); } +#endif + +internal b32 +gui_scroll_was_activated(GUI_Target *target, GUI_id scroll_context_id){ + b32 result = false; + + if (gui_id_eq(scroll_context_id, target->scroll_id)){ + if (gui_id_eq(target->active, gui_id_scrollbar())){ + result = true; + target->animating = true; + } + } + + return(result); +} internal void gui_post_scroll_vars(GUI_Target *target, GUI_Scroll_Vars *vars_in, i32_Rect region_in){