scroll system a little less sucky
							parent
							
								
									9402e2a213
								
							
						
					
					
						commit
						3b17899d8e
					
				
							
								
								
									
										27
									
								
								4ed.cpp
								
								
								
								
							
							
						
						
									
										27
									
								
								4ed.cpp
								
								
								
								
							|  | @ -422,9 +422,9 @@ COMMAND_DECL(center_view){ | |||
| 
 | ||||
|     h = view_file_height(view); | ||||
|     y -= h * .5f; | ||||
|     if (y < view->scroll_min_limit) y = view->scroll_min_limit; | ||||
|     if (y < view->file_scroll.min_y) y = view->file_scroll.min_y; | ||||
| 
 | ||||
|     view->target_y = y; | ||||
|     view->file_scroll.target_y = y; | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(word_complete){ | ||||
|  | @ -1076,9 +1076,9 @@ COMMAND_DECL(toggle_line_wrap){ | |||
|     if (view->unwrapped_lines){ | ||||
|         view->unwrapped_lines = 0; | ||||
|         file->settings.unwrapped_lines = 0; | ||||
|         view->target_x = 0; | ||||
|         view->cursor = | ||||
|             view_compute_cursor_from_pos(view, view->cursor.pos); | ||||
|         view->file_scroll.target_x = 0; | ||||
|         view->cursor =view_compute_cursor_from_pos( | ||||
|             view, view->cursor.pos); | ||||
|         view->preferred_x = view->cursor.wrapped_x; | ||||
|     } | ||||
|     else{ | ||||
|  | @ -1484,13 +1484,13 @@ COMMAND_DECL(page_down){ | |||
|     REQ_READABLE_VIEW(view); | ||||
| 
 | ||||
|     f32 height = view_file_height(view); | ||||
|     f32 max_target_y = view_compute_max_target_y(view); | ||||
|     f32 max_target_y = view->file_scroll.max_y; | ||||
| 
 | ||||
|     view->target_y += height; | ||||
|     if (view->target_y > max_target_y) view->target_y = max_target_y; | ||||
|     view->file_scroll.target_y += height; | ||||
|     if (view->file_scroll.target_y > max_target_y) view->file_scroll.target_y = max_target_y; | ||||
| 
 | ||||
|     view->cursor = view_compute_cursor_from_xy( | ||||
|         view, 0, view->target_y + (height - view->font_height)*.5f); | ||||
|         view, 0, view->file_scroll.target_y + (height - view->font_height)*.5f); | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(page_up){ | ||||
|  | @ -1498,12 +1498,13 @@ COMMAND_DECL(page_up){ | |||
|     REQ_READABLE_VIEW(view); | ||||
| 
 | ||||
|     f32 height = view_file_height(view); | ||||
|     f32 min_target_y = view->file_scroll.min_y; | ||||
| 
 | ||||
|     view->target_y -= height; | ||||
|     if (view->target_y < 0) view->target_y = 0; | ||||
|     view->file_scroll.target_y -= height; | ||||
|     if (view->file_scroll.target_y < min_target_y) view->file_scroll.target_y = min_target_y; | ||||
| 
 | ||||
|     view->cursor = view_compute_cursor_from_xy( | ||||
|         view, 0, view->target_y + (height - view->font_height)*.5f); | ||||
|         view, 0, view->file_scroll.target_y + (height - view->font_height)*.5f); | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(open_color_tweaker){ | ||||
|  | @ -1593,7 +1594,7 @@ COMMAND_DECL(set_settings){ | |||
| 
 | ||||
|                         if (!file->state.is_loading){ | ||||
|                             Relative_Scrolling scrolling = view_get_relative_scrolling(view); | ||||
|                             view->target_x = 0; | ||||
|                             view->file_scroll.target_x = 0; | ||||
|                             view->cursor = | ||||
|                                 view_compute_cursor_from_pos(view, view->cursor.pos); | ||||
|                             view_set_relative_scrolling(view, scrolling); | ||||
|  |  | |||
|  | @ -75,11 +75,11 @@ struct View{ | |||
|     Command_Map *map; | ||||
| 
 | ||||
|     Editing_File *file; | ||||
|     i32_Rect file_rect; | ||||
| 
 | ||||
|     View_UI showing_ui; | ||||
|     GUI_Target gui_target; | ||||
|     void *gui_mem; | ||||
|     GUI_Scroll_Vars gui_scroll; | ||||
|      | ||||
|     Interactive_Interaction interaction; | ||||
|     Interactive_Action action; | ||||
|  | @ -110,11 +110,10 @@ struct View{ | |||
| 
 | ||||
|     Full_Cursor cursor; | ||||
|     i32 mark; | ||||
|     f32 scroll_y, target_y, prev_target_y; | ||||
|     f32 scroll_x, target_x, prev_target_x; | ||||
|     f32 preferred_x; | ||||
|     i32 scroll_i; | ||||
|     f32 scroll_min_limit; | ||||
|      | ||||
|     GUI_Scroll_Vars file_scroll; | ||||
| 
 | ||||
|     Full_Cursor temp_highlight; | ||||
|     i32 temp_highlight_end_pos; | ||||
|  | @ -156,14 +155,14 @@ view_lock_level(View *view){ | |||
| 
 | ||||
| inline f32 | ||||
| view_file_width(View *view){ | ||||
|     i32_Rect file_rect = view->file_rect; | ||||
|     i32_Rect file_rect = view->file_scroll.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_rect; | ||||
|     i32_Rect file_rect = view->file_scroll.region; | ||||
|     f32 result = (f32)(file_rect.y1 - file_rect.y0); | ||||
|     return (result); | ||||
| } | ||||
|  | @ -1332,19 +1331,19 @@ view_get_relative_scrolling(View *view){ | |||
|     Relative_Scrolling result; | ||||
|     f32 cursor_y; | ||||
|     cursor_y = view_get_cursor_y(view); | ||||
|     result.scroll_y = cursor_y - view->scroll_y; | ||||
|     result.target_y = cursor_y - view->target_y; | ||||
|     result.scroll_min_limit = view->scroll_min_limit; | ||||
|     return result; | ||||
|     result.scroll_y = cursor_y - view->file_scroll.scroll_y; | ||||
|     result.target_y = cursor_y - view->file_scroll.target_y; | ||||
|     result.scroll_min_limit = view->file_scroll.min_y; | ||||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
| view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){ | ||||
|     f32 cursor_y; | ||||
|     cursor_y = view_get_cursor_y(view); | ||||
|     view->scroll_y = cursor_y - scrolling.scroll_y; | ||||
|     view->target_y = cursor_y - scrolling.target_y; | ||||
|     if (view->target_y < scrolling.scroll_min_limit) view->target_y = scrolling.scroll_min_limit; | ||||
|     view->file_scroll.scroll_y = cursor_y - scrolling.scroll_y; | ||||
|     view->file_scroll.target_y = cursor_y - scrolling.target_y; | ||||
|     if (view->file_scroll.target_y < scrolling.scroll_min_limit) view->file_scroll.target_y = scrolling.scroll_min_limit; | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
|  | @ -1638,17 +1637,17 @@ file_edit_cursor_fix(System_Functions *system, | |||
|                 if (view->scroll_i != new_scroll_i){ | ||||
|                     view->scroll_i = new_scroll_i; | ||||
|                     temp_cursor = view_compute_cursor_from_pos(view, view->scroll_i); | ||||
|                     y_offset = MOD(view->scroll_y, view->font_height); | ||||
|                     y_offset = MOD(view->file_scroll.scroll_y, view->font_height); | ||||
| 
 | ||||
|                     if (view->unwrapped_lines){ | ||||
|                         y_position = temp_cursor.unwrapped_y + y_offset; | ||||
|                         view->target_y += (y_position - view->scroll_y); | ||||
|                         view->scroll_y = y_position; | ||||
|                         view->file_scroll.target_y += (y_position - view->file_scroll.scroll_y); | ||||
|                         view->file_scroll.scroll_y = y_position; | ||||
|                     } | ||||
|                     else{ | ||||
|                         y_position = temp_cursor.wrapped_y + y_offset; | ||||
|                         view->target_y += (y_position - view->scroll_y); | ||||
|                         view->scroll_y = y_position; | ||||
|                         view->file_scroll.target_y += (y_position - view->file_scroll.scroll_y); | ||||
|                         view->file_scroll.scroll_y = y_position; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | @ -2654,6 +2653,7 @@ view_show_interactive(System_Functions *system, View *view, | |||
|     Models *models = view->models; | ||||
|      | ||||
|     view->showing_ui = VUI_Interactive; | ||||
|     view->gui_scroll = {0}; | ||||
|     view->action = action; | ||||
|     view->interaction = interaction; | ||||
|      | ||||
|  | @ -2683,23 +2683,6 @@ interactive_view_complete(View *view, String dest, i32 user_action){ | |||
|     Editing_File *old_file = view->file; | ||||
| 
 | ||||
|     switch (view->action){ | ||||
| #if 0 | ||||
|         case IAct_Open: | ||||
|         delayed_open(&models->delay1, models->hot_directory.string, panel); | ||||
|         delayed_touch_file(&models->delay1, old_file); | ||||
|         break; | ||||
| 
 | ||||
|         case IAct_Save_As: | ||||
|         delayed_save_as(&models->delay1, models->hot_directory.string, panel); | ||||
|         break; | ||||
| 
 | ||||
|         case IAct_New: | ||||
|         if (models->hot_directory.string.size > 0 && | ||||
|                 !char_is_slash(models->hot_directory.string.str[models->hot_directory.string.size-1])){ | ||||
|             delayed_new(&models->delay1, models->hot_directory.string, panel); | ||||
|         }break; | ||||
| #endif | ||||
| 
 | ||||
|         case IAct_Open: | ||||
|         delayed_open(&models->delay1, dest, panel); | ||||
|         delayed_touch_file(&models->delay1, old_file); | ||||
|  | @ -3435,6 +3418,7 @@ intbar_draw_string(Render_Target *target, File_Bar *bar, String str, u32 char_co | |||
|     bar->pos_x += font_string_width(target, font_id, str); | ||||
| } | ||||
| 
 | ||||
| // TODO(allen): wtf is this?
 | ||||
| internal void | ||||
| view_reinit_scrolling(View *view){ | ||||
|     Editing_File *file = view->file; | ||||
|  | @ -3459,83 +3443,83 @@ view_reinit_scrolling(View *view){ | |||
|         } | ||||
| 
 | ||||
|         target_y = (f32)FLOOR32(cursor_y - h*.5f); | ||||
|         if (target_y < view->scroll_min_limit) target_y = view->scroll_min_limit; | ||||
|         if (target_y < view->file_scroll.min_y) target_y = view->file_scroll.min_y; | ||||
|     } | ||||
| 
 | ||||
|     view->target_x = target_x; | ||||
|     view->target_y = target_y; | ||||
|     view->scroll_x = target_x; | ||||
|     view->scroll_y = target_y; | ||||
|     view->prev_target_x = -1000.f; | ||||
|     view->prev_target_y = -1000.f; | ||||
|     view->file_scroll.target_y = target_y; | ||||
|     view->file_scroll.scroll_y = target_y; | ||||
|     view->file_scroll.prev_target_y = -1000.f; | ||||
|      | ||||
|     view->file_scroll.target_x = target_x; | ||||
|     view->file_scroll.scroll_x = target_x; | ||||
|     view->file_scroll.prev_target_x = -1000.f; | ||||
| } | ||||
| 
 | ||||
| #define CursorMaxY_(m,h) ((m) - (h)*3) | ||||
| #define CursorMinY_(m,h) (-(m) + (h)*2) | ||||
| 
 | ||||
| #define CursorMaxY(m,h) (CursorMaxY_(m,h) > 0)?(CursorMaxY_(m,h)):(0) | ||||
| #define CursorMinY(m,h) (CursorMinY_(m,h) > 0)?(CursorMinY_(m,h)):(0) | ||||
| 
 | ||||
| internal i32 | ||||
| file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active){ | ||||
|     i32 result  = 0; | ||||
|     Editing_File *file = view->file; | ||||
|     if (file && !file->state.is_loading){ | ||||
|         // TODO(allen): rewrite with real scrolling system now.
 | ||||
|         f32 line_height = (f32)view->font_height; | ||||
|         f32 cursor_y = view_get_cursor_y(view); | ||||
|         f32 target_y = view->target_y; | ||||
|         i32 lowest_line = view_compute_lowest_line(view); | ||||
|          | ||||
|         f32 delta_y = 3.f*line_height; | ||||
|          | ||||
|         f32 max_y = view_file_height(view); | ||||
|         f32 cursor_y = view_get_cursor_y(view); | ||||
|          | ||||
|         f32 max_visible_y = view_file_height(view); | ||||
|         f32 max_x = view_file_width(view); | ||||
|         f32 max_target_y = view_compute_max_target_y(lowest_line, (i32)line_height, max_y); | ||||
|         f32 cursor_max_y = max_y - view->font_height * 3; | ||||
| 
 | ||||
|         f32 cursor_x = view_get_cursor_x(view); | ||||
|          | ||||
|          | ||||
|         GUI_Scroll_Vars scroll_vars = view->gui_target.scroll_original; | ||||
|         f32 target_y = scroll_vars.target_y; | ||||
|         f32 target_x = scroll_vars.target_x; | ||||
|          | ||||
|         f32 cursor_max_y = CursorMaxY(max_visible_y, line_height); | ||||
|         f32 cursor_min_y = CursorMinY(scroll_vars.min_y, line_height); | ||||
|          | ||||
|         if (cursor_y > target_y + cursor_max_y){ | ||||
|             target_y = cursor_y - cursor_max_y + delta_y; | ||||
|         } | ||||
|         if (cursor_y < target_y - view->scroll_min_limit){ | ||||
|             target_y = cursor_y - delta_y + view->scroll_min_limit; | ||||
|         if (cursor_y < target_y + cursor_min_y){ | ||||
|             target_y = cursor_y - delta_y - cursor_min_y; | ||||
|         } | ||||
| 
 | ||||
|         if (target_y > max_target_y) target_y = max_target_y; | ||||
|         if (target_y < view->scroll_min_limit) target_y = view->scroll_min_limit; | ||||
|         view->target_y = target_y; | ||||
| 
 | ||||
|         f32 cursor_x = view_get_cursor_x(view); | ||||
|         f32 target_x = view->target_x; | ||||
|          | ||||
|         if (target_y > scroll_vars.max_y) target_y = scroll_vars.max_y; | ||||
|         if (target_y < scroll_vars.min_y) target_y = view->file_scroll.min_y; | ||||
|          | ||||
|         if (cursor_x < target_x){ | ||||
|             target_x = (f32)Max(0, cursor_x - max_x/2); | ||||
|         } | ||||
|         else if (cursor_x >= target_x + max_x){ | ||||
|             target_x = (f32)(cursor_x - max_x/2); | ||||
|         } | ||||
| 
 | ||||
|         view->target_x = target_x; | ||||
| 
 | ||||
|         b32 is_new_target = 0; | ||||
|         if (view->target_x != view->prev_target_x) is_new_target = 1; | ||||
|         if (view->target_y != view->prev_target_y) is_new_target = 1; | ||||
| 
 | ||||
|         if (view->models->scroll_rule( | ||||
|                 view->target_x, view->target_y, | ||||
|                 &view->scroll_x, &view->scroll_y, | ||||
|                 (view->id) + 1, is_new_target)){ | ||||
|             result = 1; | ||||
|          | ||||
|         if (target_x != scroll_vars.target_x || target_y != scroll_vars.target_y){ | ||||
|             view->gui_target.scroll_updated.target_x = target_x; | ||||
|             view->gui_target.scroll_updated.target_y = target_y; | ||||
|             gui_activate_scrolling(&view->gui_target); | ||||
|         } | ||||
| 
 | ||||
|         view->prev_target_x = view->target_x; | ||||
|         view->prev_target_y = view->target_y; | ||||
| 
 | ||||
|          | ||||
|         if (file->state.paste_effect.tick_down > 0){ | ||||
|             --file->state.paste_effect.tick_down; | ||||
|             result = 1; | ||||
|         } | ||||
| 
 | ||||
|          | ||||
|         if (user_input->mouse.press_l && is_active){ | ||||
|             f32 rx = (f32)(user_input->mouse.x - region.x0); | ||||
|             f32 ry = (f32)(user_input->mouse.y - region.y0); | ||||
| 
 | ||||
|             if (ry >= -view->scroll_min_limit){ | ||||
|             if (ry >= -view->file_scroll.min_y){ | ||||
|                 view_set_widget(view, FWIDG_NONE); | ||||
|                 if (rx >= 0 && rx < max_x && ry >= 0 && ry < max_y){ | ||||
|                     view_cursor_move(view, rx + view->scroll_x, ry + view->scroll_y, 1); | ||||
|                 if (rx >= 0 && rx < max_x && ry >= 0 && ry < max_visible_y){ | ||||
|                     view_cursor_move(view, rx + scroll_vars.scroll_x, ry + scroll_vars.scroll_y, 1); | ||||
|                     view->mode = {}; | ||||
|                 } | ||||
|             } | ||||
|  | @ -3551,7 +3535,6 @@ internal void | |||
| view_do_queries(View *view, GUI_Target *target){ | ||||
|     Query_Slot *slot; | ||||
|     Query_Bar *bar; | ||||
|      | ||||
|     for (slot = view->query_set.used_slot; slot != 0; slot = slot->next){ | ||||
|         bar = slot->query_bar; | ||||
|         gui_do_text_field(target, bar->prompt, bar->string); | ||||
|  | @ -3561,9 +3544,7 @@ view_do_queries(View *view, GUI_Target *target){ | |||
| internal void | ||||
| do_widget(View *view, GUI_Target *target){ | ||||
|     gui_begin_serial_section(target); | ||||
|     { | ||||
|         view_do_queries(view, target); | ||||
|     } | ||||
|     view_do_queries(view, target); | ||||
|     gui_end_serial_section(target); | ||||
| } | ||||
| 
 | ||||
|  | @ -3572,44 +3553,36 @@ step_file_view(System_Functions *system, View *view, b32 is_active){ | |||
|     GUI_Target *target = &view->gui_target; | ||||
|     Models *models = view->models; | ||||
|      | ||||
|     f32 max_y = view_file_height(view); | ||||
|     f32 min_target_y = view->file_scroll.min_y; | ||||
|     f32 max_target_y = view->file_scroll.max_y; | ||||
|      | ||||
|     i32 lowest_line = view_compute_lowest_line(view); | ||||
|     f32 min_target_y = view->scroll_min_limit; | ||||
|     f32 max_target_y = view_compute_max_target_y(lowest_line, view->font_height, max_y); | ||||
|      | ||||
| 
 | ||||
|     gui_begin_top_level(target); | ||||
|     { | ||||
|         gui_do_top_bar(target); | ||||
| 
 | ||||
|          | ||||
|         if (view->showing_ui == VUI_None){ | ||||
|             gui_begin_overlap(target); | ||||
|             do_widget(view, target); | ||||
| 
 | ||||
|              | ||||
|             gui_begin_serial_section(target); | ||||
|             { | ||||
|                 i32_Rect scroll_rect = {0}; | ||||
|                 f32 v = unlerp(min_target_y, view->target_y, max_target_y); | ||||
|                 i32 line_height = view->font_height; | ||||
|                 f32 old_cursor_y = view_get_cursor_y(view); | ||||
|                 f32 cursor_y = old_cursor_y; | ||||
|                 f32 cursor_max_y = max_y - view->font_height * 3; | ||||
| 
 | ||||
|                 f32 cursor_max_y = CursorMaxY(view_file_height(view), line_height); | ||||
|                 f32 cursor_min_y = CursorMinY(min_target_y, line_height); | ||||
|                 f32 delta = 9.f * view->font_height; | ||||
|                 f32 lerp_space_delta = (delta);  | ||||
|                 if (max_target_y > min_target_y){ | ||||
|                     lerp_space_delta /= (max_target_y - min_target_y); | ||||
|                 } | ||||
| 
 | ||||
|                 if (gui_start_scrollable(target, view->showing_ui, &v, lerp_space_delta, &scroll_rect)){ | ||||
|                     view->target_y = lerp(min_target_y, v, max_target_y); | ||||
| 
 | ||||
|                     if (view->target_y < min_target_y) view->target_y = min_target_y; | ||||
|                     if (view->target_y > max_target_y) view->target_y = max_target_y; | ||||
| 
 | ||||
|                     if (cursor_y > view->target_y + cursor_max_y) cursor_y = view->target_y + cursor_max_y; | ||||
|                     if (cursor_y < view->target_y - view->scroll_min_limit) cursor_y = view->target_y - view->scroll_min_limit; | ||||
| 
 | ||||
|                 f32 target_y; | ||||
|                  | ||||
|                 if (gui_get_scroll_vars(target, view->showing_ui, &view->file_scroll)){ | ||||
|                     target_y = view->file_scroll.target_y; | ||||
| 					if (cursor_y > target_y + cursor_max_y){ | ||||
|                         cursor_y = target_y + cursor_max_y; | ||||
|                     } | ||||
|                     if (target_y != 0 && cursor_y < target_y + cursor_min_y){ | ||||
|                         cursor_y = target_y + cursor_min_y; | ||||
|                     } | ||||
|                      | ||||
|                     if (cursor_y != old_cursor_y){ | ||||
|                         if (cursor_y > old_cursor_y){ | ||||
|                             cursor_y += view->font_height; | ||||
|  | @ -3619,17 +3592,17 @@ step_file_view(System_Functions *system, View *view, b32 is_active){ | |||
| 						} | ||||
|                         view->cursor = view_compute_cursor_from_xy(view, view->preferred_x, cursor_y); | ||||
|                     } | ||||
|                 } | ||||
| 				} | ||||
|                  | ||||
|                 view->file_rect = scroll_rect; | ||||
|                 gui_start_scrollable(target, view->showing_ui, view->file_scroll, delta); | ||||
|                  | ||||
|                 if (view->file_scroll.scroll_y < min_target_y) view->file_scroll.scroll_y = min_target_y; | ||||
|                 if (view->file_scroll.scroll_y > max_target_y) view->file_scroll.scroll_y = max_target_y; | ||||
|                  | ||||
|                 if (view->scroll_y < min_target_y) view->scroll_y = min_target_y; | ||||
|                 if (view->scroll_y > max_target_y) view->scroll_y = max_target_y; | ||||
| 
 | ||||
|                 gui_do_file(target); | ||||
|             } | ||||
|             gui_end_serial_section(target); | ||||
| 
 | ||||
|              | ||||
|             gui_end_overlap(target); | ||||
|         } | ||||
|         else{ | ||||
|  | @ -3675,8 +3648,9 @@ step_file_view(System_Functions *system, View *view, b32 is_active){ | |||
|                         } | ||||
|                         gui_do_text_field(target, message, text); | ||||
| 
 | ||||
|                         i32_Rect scroll_rect = {0}; | ||||
|                         gui_start_scrollable(target, view->showing_ui, 0, 3.f, &scroll_rect); | ||||
|                         gui_get_scroll_vars(target, view->showing_ui, &view->gui_scroll); | ||||
|                         gui_start_scrollable(target, view->showing_ui, view->gui_scroll, 9.f * view->font_height); | ||||
| 
 | ||||
|                         for (i = 0; i < files->count; ++i, ++info){ | ||||
|                             append(&full_path, info->filename); | ||||
|                             terminate_with_null(&full_path); | ||||
|  | @ -3709,10 +3683,21 @@ step_file_view(System_Functions *system, View *view, b32 is_active){ | |||
|         } | ||||
|     } | ||||
|     gui_end_top_level(target); | ||||
| 
 | ||||
|     return(1); | ||||
| } | ||||
| 
 | ||||
| internal f32 | ||||
| view_get_scroll_y(View *view){ | ||||
|     f32 v; | ||||
|     if (view->showing_ui == VUI_None){ | ||||
|         v = view->file_scroll.scroll_y; | ||||
| 	} | ||||
|     else{ | ||||
|         v = view->gui_scroll.scroll_y; | ||||
| 	} | ||||
|     return(v); | ||||
| } | ||||
| 
 | ||||
| internal i32 | ||||
| do_input_file_view(System_Functions *system, Exchange *exchange, | ||||
|     View *view, i32_Rect rect, b32 is_active, Input_Summary *user_input){ | ||||
|  | @ -3722,7 +3707,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange, | |||
|     GUI_Session gui_session; | ||||
|     GUI_Header *h; | ||||
|     GUI_Target *target = &view->gui_target; | ||||
|      | ||||
| 
 | ||||
|     gui_session_init(&gui_session, rect, view->font_height); | ||||
|      | ||||
|     target->active = {0}; | ||||
|  | @ -3736,7 +3721,20 @@ do_input_file_view(System_Functions *system, Exchange *exchange, | |||
|                  | ||||
|                 case guicom_file: | ||||
|                 { | ||||
|                     view->scroll_min_limit = -(f32)(gui_session.clip_rect.y0 - gui_session.rect.y0); | ||||
|                     f32 old_min_y = view->gui_target.scroll_updated.min_y; | ||||
|                     f32 new_min_y = -(f32)(gui_session.clip_rect.y0 - gui_session.rect.y0); | ||||
|                     if (old_min_y != new_min_y){ | ||||
|                         view->gui_target.scroll_updated.min_y = new_min_y; | ||||
|                         gui_activate_scrolling(&view->gui_target); | ||||
|                     } | ||||
|                      | ||||
|                     f32 old_max_y = view->gui_target.scroll_updated.max_y; | ||||
|                     f32 new_max_y = view_compute_max_target_y(view); | ||||
|                     if (old_max_y != new_max_y){ | ||||
| 						view->gui_target.scroll_updated.max_y = new_max_y; | ||||
|                         gui_activate_scrolling(&view->gui_target); | ||||
| 					} | ||||
|                      | ||||
|                     if (view->reinit_scrolling){ | ||||
|                         view_reinit_scrolling(view); | ||||
|                     } | ||||
|  | @ -3780,10 +3778,12 @@ do_input_file_view(System_Functions *system, Exchange *exchange, | |||
|                             target->hot = id; | ||||
|                         } | ||||
|                         if (user_input->mouse.release_l && gui_id_eq(target->hot, id)){ | ||||
|                             target->active = gui_id_scrollbar(); | ||||
|                             target->hot = {0}; | ||||
|                             target->scroll_v -= target->scroll_delta; | ||||
|                             if (target->scroll_v < 0) target->scroll_v = 0; | ||||
|                             target->scroll_updated.target_y -= target->delta; | ||||
|                             if (target->scroll_updated.target_y < target->scroll_updated.min_y){ | ||||
|                                 target->scroll_updated.target_y = target->scroll_updated.min_y; | ||||
|                             } | ||||
|                             gui_activate_scrolling(target); | ||||
|                         } | ||||
| 					} | ||||
|                     else if (gui_id_eq(target->hover, id)){ | ||||
|  | @ -3796,6 +3796,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange, | |||
|                     GUI_id id = gui_id_scrollbar_slider(); | ||||
|                     i32 mx = user_input->mouse.x; | ||||
|                     i32 my = user_input->mouse.y; | ||||
|                     f32 v = 0; | ||||
| 					 | ||||
|                     if (hit_check(mx, my, gui_session.rect)){ | ||||
|                         target->hover = id; | ||||
|  | @ -3808,17 +3809,23 @@ do_input_file_view(System_Functions *system, Exchange *exchange, | |||
| 					} | ||||
|                      | ||||
|                     if (gui_id_eq(target->hot, id)){ | ||||
|                         target->active = gui_id_scrollbar(); | ||||
|                         target->scroll_v = unlerp(gui_session.scroll_top, (f32)my, gui_session.scroll_bottom); | ||||
|                         if (target->scroll_v < 0) target->scroll_v = 0; | ||||
|                         if (target->scroll_v > 1) target->scroll_v = 1; | ||||
|                         v = unlerp(gui_session.scroll_top, (f32)my, gui_session.scroll_bottom); | ||||
|                         if (v < 0) v = 0; | ||||
|                         if (v > 1.f) v = 1.f; | ||||
|                         target->scroll_updated.target_y = lerp(target->scroll_updated.min_y, v, target->scroll_updated.max_y); | ||||
|                         gui_activate_scrolling(target); | ||||
|                     } | ||||
|                      | ||||
|                     if (user_input->mouse.wheel != 0){ | ||||
|                         target->active = gui_id_scrollbar(); | ||||
|                         target->scroll_v += user_input->mouse.wheel*target->scroll_delta; | ||||
|                         if (target->scroll_v < 0) target->scroll_v = 0; | ||||
|                         if (target->scroll_v > 1) target->scroll_v = 1; | ||||
|                         target->scroll_updated.target_y += user_input->mouse.wheel*target->delta; | ||||
| 
 | ||||
|                         if (target->scroll_updated.target_y < target->scroll_updated.min_y){ | ||||
|                             target->scroll_updated.target_y = target->scroll_updated.min_y; | ||||
|                         } | ||||
|                         if (target->scroll_updated.target_y > target->scroll_updated.max_y){ | ||||
|                             target->scroll_updated.target_y = target->scroll_updated.max_y; | ||||
|                         } | ||||
|                         gui_activate_scrolling(target); | ||||
| 					} | ||||
|                 }break; | ||||
| 
 | ||||
|  | @ -3834,10 +3841,12 @@ do_input_file_view(System_Functions *system, Exchange *exchange, | |||
|                             target->hot = id; | ||||
|                         } | ||||
|                         if (user_input->mouse.release_l && gui_id_eq(target->hot, id)){ | ||||
|                             target->active = gui_id_scrollbar(); | ||||
|                             target->hot = {0}; | ||||
|                             target->scroll_v += target->scroll_delta; | ||||
|                             if (target->scroll_v > 1) target->scroll_v = 1; | ||||
|                             target->scroll_updated.target_y += target->delta; | ||||
|                             if (target->scroll_updated.target_y > target->scroll_updated.max_y){ | ||||
|                                 target->scroll_updated.target_y = target->scroll_updated.max_y; | ||||
|                             } | ||||
|                             gui_activate_scrolling(target); | ||||
|                         } | ||||
| 					} | ||||
|                     else if (gui_id_eq(target->hover, id)){ | ||||
|  | @ -3852,6 +3861,26 @@ do_input_file_view(System_Functions *system, Exchange *exchange, | |||
|         target->hot = {0}; | ||||
| 	} | ||||
|      | ||||
|     { | ||||
|         GUI_Scroll_Vars scroll_vars = view->gui_target.scroll_updated; | ||||
|         b32 is_new_target = 0; | ||||
|         if (scroll_vars.target_x != scroll_vars.prev_target_x) is_new_target = 1; | ||||
|         if (scroll_vars.target_y != scroll_vars.prev_target_y) is_new_target = 1; | ||||
| 
 | ||||
|         if (view->models->scroll_rule( | ||||
|                 scroll_vars.target_x, scroll_vars.target_y, | ||||
|                 &scroll_vars.scroll_x, &scroll_vars.scroll_y, | ||||
|                 (view->id) + 1, is_new_target)){ | ||||
|             result = 1; | ||||
|             gui_activate_scrolling(&view->gui_target); | ||||
|         } | ||||
| 
 | ||||
|         scroll_vars.prev_target_x = scroll_vars.target_x; | ||||
|         scroll_vars.prev_target_y = scroll_vars.target_y; | ||||
|          | ||||
|         view->gui_target.scroll_updated = scroll_vars; | ||||
| 	} | ||||
|      | ||||
|     return(result); | ||||
|      | ||||
| #if 0 | ||||
|  | @ -3994,8 +4023,8 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target | |||
|     Buffer_Render_Options opts = {}; | ||||
| 
 | ||||
|     f32 *wraps = view->line_wrap_y; | ||||
|     f32 scroll_x = view->scroll_x; | ||||
|     f32 scroll_y = view->scroll_y; | ||||
|     f32 scroll_x = view->file_scroll.scroll_x; | ||||
|     f32 scroll_y = view->file_scroll.scroll_y; | ||||
| 
 | ||||
|     { | ||||
|         render_cursor = buffer_get_start_cursor(&file->state.buffer, wraps, scroll_y, | ||||
|  | @ -4180,7 +4209,7 @@ do_render_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Re | |||
|             } | ||||
|             else{ | ||||
|                 char line_number_space[30]; | ||||
|                 String line_number = make_string(line_number_space, 0, 30); | ||||
|                 String line_number = make_fixed_width_string(line_number_space); | ||||
|                 append(&line_number, " L#"); | ||||
|                 append_int_to_str(view->cursor.line, &line_number); | ||||
| 
 | ||||
|  | @ -4271,8 +4300,12 @@ do_render_file_view(System_Functions *system, Exchange *exchange, | |||
|     GUI_Header *h; | ||||
|     GUI_Target *gui_target = &view->gui_target; | ||||
|      | ||||
|     f32 v; | ||||
|      | ||||
|     gui_session_init(&gui_session, rect, view->font_height); | ||||
|      | ||||
|     v = view_get_scroll_y(view); | ||||
|      | ||||
|     for (h = (GUI_Header*)gui_target->push.base; | ||||
|         h->type; | ||||
|         h = NextHeader(h)){ | ||||
|  | @ -4281,13 +4314,11 @@ do_render_file_view(System_Functions *system, Exchange *exchange, | |||
|                 case guicom_top_bar: | ||||
|                 { | ||||
|                     do_render_file_bar(target, view, file, gui_session.rect); | ||||
|                 } | ||||
|                 break; | ||||
|                 }break; | ||||
| 
 | ||||
|                 case guicom_file: | ||||
|                 { | ||||
|                     target->push_clip(target, gui_session.clip_rect); | ||||
|                     view->scroll_min_limit = -(f32)(gui_session.clip_rect.y0 - gui_session.rect.y0); | ||||
|                     if (view->reinit_scrolling){ | ||||
|                         view_reinit_scrolling(view); | ||||
|                     } | ||||
|  | @ -4753,12 +4784,6 @@ live_set_alloc_view(Live_Views *live_set, Panel *panel, Models *models){ | |||
|     result.view->models = models; | ||||
|     result.view->scrub_max = 1; | ||||
| 
 | ||||
| #if 0 | ||||
|     // TODO(allen): Make "interactive" mode customizable just like the query bars!
 | ||||
|     result.view->query = make_fixed_width_string(result.view->query_); | ||||
|     result.view->dest = make_fixed_width_string(result.view->dest_); | ||||
| #endif | ||||
| 
 | ||||
|     init_query_set(&result.view->query_set); | ||||
| 
 | ||||
|     { | ||||
|  |  | |||
							
								
								
									
										102
									
								
								4ed_gui.cpp
								
								
								
								
							
							
						
						
									
										102
									
								
								4ed_gui.cpp
								
								
								
								
							|  | @ -50,7 +50,7 @@ free_query_slot(Query_Set *set, Query_Bar *match_bar){ | |||
|         if (slot->query_bar == match_bar) break; | ||||
|         prev = slot; | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     if (slot){ | ||||
|         if (prev){ | ||||
|             prev->next = slot->next; | ||||
|  | @ -73,6 +73,19 @@ struct GUI_id{ | |||
|     u64 id[1]; | ||||
| }; | ||||
| 
 | ||||
| struct GUI_Scroll_Vars{ | ||||
|     f32 scroll_y; | ||||
|     f32 target_y; | ||||
|     f32 prev_target_y; | ||||
|     f32 min_y, max_y; | ||||
|      | ||||
|     f32 scroll_x; | ||||
|     f32 target_x; | ||||
|     f32 prev_target_x; | ||||
|      | ||||
|     i32_Rect region; | ||||
| }; | ||||
| 
 | ||||
| struct GUI_Target{ | ||||
|     Partition push; | ||||
|      | ||||
|  | @ -80,10 +93,10 @@ struct GUI_Target{ | |||
|     GUI_id hot; | ||||
|     GUI_id hover; | ||||
|      | ||||
|     f32 scroll_v; | ||||
|     f32 scroll_delta; | ||||
|     GUI_Scroll_Vars scroll_original; | ||||
|     GUI_Scroll_Vars scroll_updated; | ||||
|     f32 delta; | ||||
|     u32 scroll_id; | ||||
|     i32_Rect scrollable_area; | ||||
| }; | ||||
| 
 | ||||
| struct GUI_Header{ | ||||
|  | @ -237,7 +250,6 @@ gui_push_string(GUI_Target *target, GUI_Header *h, String s){ | |||
| internal void | ||||
| gui_begin_top_level(GUI_Target *target){ | ||||
|     target->push.pos = 0; | ||||
|     target->scroll_delta = 0; | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
|  | @ -328,31 +340,35 @@ gui_id_scrollbar_bottom(){ | |||
| } | ||||
| 
 | ||||
| internal b32 | ||||
| gui_start_scrollable(GUI_Target *target, u32 scroll_id, f32 *v, f32 d, i32_Rect *rect){ | ||||
| gui_get_scroll_vars(GUI_Target *target, u32 scroll_id, GUI_Scroll_Vars *vars_out){ | ||||
|     b32 result = 0; | ||||
|     GUI_Header *h; | ||||
|      | ||||
|     target->scroll_delta = d; | ||||
|     h = gui_push_simple_command(target, guicom_scrollable); | ||||
|     if (gui_id_eq(gui_id_scrollbar(), target->active) && target->scroll_id == scroll_id){ | ||||
|         if (v) *v = target->scroll_v; | ||||
|     if (gui_id_eq(target->active, gui_id_scrollbar()) && target->scroll_id == scroll_id){ | ||||
|         *vars_out = target->scroll_updated; | ||||
|         result = 1; | ||||
| 	} | ||||
|     else{ | ||||
|         if (v) target->scroll_v = *v; | ||||
| 	} | ||||
|     if (target->scroll_id == scroll_id){ | ||||
|         *rect = target->scrollable_area; | ||||
| 	} | ||||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
| gui_start_scrollable(GUI_Target *target, u32 scroll_id, GUI_Scroll_Vars scroll_vars, f32 delta){ | ||||
|     GUI_Header *h; | ||||
|      | ||||
|     target->delta = delta; | ||||
|     h = gui_push_simple_command(target, guicom_scrollable); | ||||
|      | ||||
|     target->scroll_original = scroll_vars; | ||||
|     target->scroll_updated = scroll_vars; | ||||
|     target->scroll_id = scroll_id; | ||||
|      | ||||
|     gui_push_simple_command(target, guicom_scrollable_top); | ||||
|     gui_push_simple_command(target, guicom_scrollable_slider); | ||||
|     gui_push_simple_command(target, guicom_scrollable_bottom); | ||||
|      | ||||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
| gui_activate_scrolling(GUI_Target *target){ | ||||
|     target->active = gui_id_scrollbar(); | ||||
| } | ||||
| 
 | ||||
| struct GUI_Section{ | ||||
|     b32 overlapped; | ||||
|  | @ -470,12 +486,16 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ | |||
|     i32_Rect rect = {0}; | ||||
|     i32 y = 0; | ||||
|     i32 end_v = -1; | ||||
|     f32 lerp_space_scroll_v = 0; | ||||
|     i32 scroll_v = (i32)target->scroll_original.scroll_y; | ||||
|      | ||||
|     Assert(session->t < ArrayCount(session->sections)); | ||||
|     section = session->sections + session->t; | ||||
|     y = section->v; | ||||
|      | ||||
|     if (y < session->full_rect.y1){ | ||||
|     if (!session->is_scrollable) scroll_v = 0; | ||||
|      | ||||
|     if (y - scroll_v < session->full_rect.y1){ | ||||
|         switch (h->type){ | ||||
|             case guicom_null: Assert(0); break; | ||||
|              | ||||
|  | @ -525,6 +545,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ | |||
|             rect = gui_layout_top_bottom(session, y, session->full_rect.y1); | ||||
|             end_v = rect.y1; | ||||
|             end_section = section; | ||||
|             scroll_v = 0; | ||||
|             break; | ||||
|              | ||||
|             case guicom_text_field: | ||||
|  | @ -552,10 +573,15 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ | |||
|             session->scroll_rect = rect; | ||||
|             session->is_scrollable = 1; | ||||
| 
 | ||||
|             target->scrollable_area.x0 = session->full_rect.x0; | ||||
|             target->scrollable_area.x1 = rect.x0; | ||||
|             target->scrollable_area.y0 = rect.y0; | ||||
|             target->scrollable_area.y1 = rect.y1; | ||||
|             { | ||||
|                 i32_Rect scrollable_rect; | ||||
|                 scrollable_rect.x0 = session->full_rect.x0; | ||||
|                 scrollable_rect.x1 = rect.x0; | ||||
|                 scrollable_rect.y0 = rect.y0; | ||||
|                 scrollable_rect.y1 = rect.y1; | ||||
|                  | ||||
|                 target->scroll_updated.region = scrollable_rect; | ||||
| 			} | ||||
|             break; | ||||
|              | ||||
|             case guicom_scrollable_top: | ||||
|  | @ -563,13 +589,17 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ | |||
|             Assert(!section->overlapped); | ||||
|             give_to_user = 1; | ||||
|             gui_scrollbar_top(session->scroll_rect, &rect); | ||||
|             scroll_v = 0; | ||||
|             break; | ||||
|              | ||||
|             case guicom_scrollable_slider: | ||||
|             Assert(session->is_scrollable); | ||||
|             Assert(!section->overlapped); | ||||
|             give_to_user = 1; | ||||
|             gui_scrollbar_slider(session->scroll_rect, &rect, target->scroll_v, &session->scroll_top, &session->scroll_bottom); | ||||
|             lerp_space_scroll_v = unlerp( | ||||
|                 (f32)target->scroll_original.min_y, (f32)target->scroll_original.target_y, (f32)target->scroll_original.max_y); | ||||
|             gui_scrollbar_slider(session->scroll_rect, &rect, lerp_space_scroll_v, &session->scroll_top, &session->scroll_bottom); | ||||
|             scroll_v = 0; | ||||
|             break; | ||||
|              | ||||
|             case guicom_scrollable_bottom: | ||||
|  | @ -577,6 +607,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ | |||
|             Assert(!section->overlapped); | ||||
|             give_to_user = 1; | ||||
|             gui_scrollbar_bottom(session->scroll_rect, &rect); | ||||
|             scroll_v = 0; | ||||
|             break; | ||||
|         } | ||||
|          | ||||
|  | @ -591,11 +622,22 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ | |||
|                 } | ||||
|             } | ||||
|              | ||||
|             session->rect = rect; | ||||
|             if (rect.y0 < max_v){ | ||||
|                 rect.y0 = max_v; | ||||
|             rect.y0 -= scroll_v; | ||||
|             rect.y1 -= scroll_v; | ||||
|              | ||||
|             if (rect.y1 > session->full_rect.y0){ | ||||
|                 session->rect = rect; | ||||
| 
 | ||||
|                 rect.y0 += scroll_v; | ||||
|                 if (rect.y0 < max_v){ | ||||
|                     rect.y0 = max_v; | ||||
|                 } | ||||
|                 rect.y0 -= scroll_v; | ||||
|                 session->clip_rect = rect; | ||||
|             } | ||||
|             session->clip_rect = rect; | ||||
|             else{ | ||||
|                 give_to_user = 0; | ||||
| 			} | ||||
|         } | ||||
|          | ||||
|         if (end_section){ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster