scrolling system at minimal-suckage

master
Allen Webster 2016-04-03 14:48:50 -04:00
parent 3b17899d8e
commit c877b57f65
2 changed files with 229 additions and 169 deletions

View File

@ -3504,7 +3504,6 @@ file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active)
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);
}
if (file->state.paste_effect.tick_down > 0){
@ -3594,12 +3593,14 @@ step_file_view(System_Functions *system, View *view, b32 is_active){
}
}
gui_start_scrollable(target, view->showing_ui, view->file_scroll, delta);
gui_begin_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;
gui_do_file(target);
gui_end_scrollable(target);
}
gui_end_serial_section(target);
@ -3649,7 +3650,7 @@ step_file_view(System_Functions *system, View *view, b32 is_active){
gui_do_text_field(target, message, text);
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);
gui_begin_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);
@ -3677,6 +3678,8 @@ step_file_view(System_Functions *system, View *view, b32 is_active){
}
full_path.size = r;
}
gui_end_scrollable(target);
}break;
}break;
}
@ -3703,6 +3706,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange,
View *view, i32_Rect rect, b32 is_active, Input_Summary *user_input){
i32 result = 0;
b32 is_file_scroll = 0;
GUI_Session gui_session;
GUI_Header *h;
@ -3725,14 +3729,12 @@ do_input_file_view(System_Functions *system, Exchange *exchange,
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){
@ -3741,6 +3743,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange,
if (file_step(view, gui_session.rect, user_input, is_active)){
result = 1;
}
is_file_scroll = 1;
}break;
case guicom_text_field: break;
@ -3853,6 +3856,23 @@ do_input_file_view(System_Functions *system, Exchange *exchange,
target->hover = {0};
}
}break;
case guicom_scrollable_section_end:
{
if (!is_file_scroll){
f32 old_min_y = view->gui_target.scroll_updated.min_y;
f32 new_min_y = gui_session.suggested_min_y;
if (old_min_y != new_min_y){
view->gui_target.scroll_updated.min_y = new_min_y;
}
f32 old_max_y = view->gui_target.scroll_updated.max_y;
f32 new_max_y = gui_session.suggested_max_y;
if (old_max_y != new_max_y){
view->gui_target.scroll_updated.max_y = new_max_y;
}
}
}break;
}
}
}
@ -3872,7 +3892,6 @@ do_input_file_view(System_Functions *system, Exchange *exchange,
&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;
@ -4318,14 +4337,12 @@ do_render_file_view(System_Functions *system, Exchange *exchange,
case guicom_file:
{
target->push_clip(target, gui_session.clip_rect);
if (view->reinit_scrolling){
view_reinit_scrolling(view);
}
if (file && file_is_ready(file)){
result = draw_file_loaded(view, gui_session.rect, is_active, target);
}
target->pop_clip(target);
}break;
case guicom_text_field:
@ -4412,6 +4429,16 @@ do_render_file_view(System_Functions *system, Exchange *exchange,
draw_rectangle(target, box, back);
draw_rectangle_outline(target, box, outline);
}break;
case guicom_scrollable_section_begin:
{
target->push_clip(target, gui_session.absolute_rect);
}break;
case guicom_scrollable_section_end:
{
target->pop_clip(target);
}break;
}
}
}

View File

@ -123,6 +123,8 @@ enum GUI_Command_Type{
guicom_scrollable_top,
guicom_scrollable_slider,
guicom_scrollable_bottom,
guicom_scrollable_section_begin,
guicom_scrollable_section_end,
};
internal b32
@ -247,16 +249,6 @@ gui_push_string(GUI_Target *target, GUI_Header *h, String s){
gui_push_string(target, h, s, 0);
}
internal void
gui_begin_top_level(GUI_Target *target){
target->push.pos = 0;
}
internal void
gui_end_top_level(GUI_Target *target){
gui_push_simple_command(target, guicom_null);
}
internal void
gui_begin_overlap(GUI_Target *target){
gui_push_simple_command(target, guicom_begin_overlap);
@ -277,6 +269,16 @@ gui_end_serial_section(GUI_Target *target){
gui_push_simple_command(target, guicom_end_serial);
}
internal void
gui_begin_top_level(GUI_Target *target){
target->push.pos = 0;
}
internal void
gui_end_top_level(GUI_Target *target){
gui_push_simple_command(target, guicom_null);
}
internal void
gui_do_top_bar(GUI_Target *target){
gui_push_simple_command(target, guicom_top_bar);
@ -342,15 +344,17 @@ gui_id_scrollbar_bottom(){
internal b32
gui_get_scroll_vars(GUI_Target *target, u32 scroll_id, GUI_Scroll_Vars *vars_out){
b32 result = 0;
if (gui_id_eq(target->active, gui_id_scrollbar()) && target->scroll_id == scroll_id){
if (target->scroll_id == scroll_id){
*vars_out = target->scroll_updated;
if (gui_id_eq(target->active, gui_id_scrollbar())){
result = 1;
}
}
return(result);
}
internal void
gui_start_scrollable(GUI_Target *target, u32 scroll_id, GUI_Scroll_Vars scroll_vars, f32 delta){
gui_begin_scrollable(GUI_Target *target, u32 scroll_id, GUI_Scroll_Vars scroll_vars, f32 delta){
GUI_Header *h;
target->delta = delta;
@ -363,6 +367,12 @@ gui_start_scrollable(GUI_Target *target, u32 scroll_id, GUI_Scroll_Vars scroll_v
gui_push_simple_command(target, guicom_scrollable_top);
gui_push_simple_command(target, guicom_scrollable_slider);
gui_push_simple_command(target, guicom_scrollable_bottom);
gui_push_simple_command(target, guicom_scrollable_section_begin);
}
internal void
gui_end_scrollable(GUI_Target *target){
gui_push_simple_command(target, guicom_scrollable_section_end);
}
internal void
@ -379,6 +389,10 @@ struct GUI_Session{
i32_Rect full_rect;
i32_Rect clip_rect;
i32_Rect rect;
i32_Rect absolute_rect;
f32 suggested_min_y;
f32 suggested_max_y;
i32 line_height;
i32 scroll_bar_w;
@ -483,6 +497,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){
GUI_Section *prev_section = 0;
GUI_Section *end_section = 0;
b32 give_to_user = 0;
b32 always_give_to_user = 0;
i32_Rect rect = {0};
i32 y = 0;
i32 end_v = -1;
@ -495,7 +510,6 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){
if (!session->is_scrollable) scroll_v = 0;
if (y - scroll_v < session->full_rect.y1){
switch (h->type){
case guicom_null: Assert(0); break;
@ -609,9 +623,21 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){
gui_scrollbar_bottom(session->scroll_rect, &rect);
scroll_v = 0;
break;
case guicom_scrollable_section_begin:
always_give_to_user = 1;
session->suggested_min_y = -(f32)(session->clip_rect.y0 - session->rect.y0);
session->suggested_max_y = (f32)(session->absolute_rect.y1 - session->full_rect.y1 * .5f);
rect = gui_layout_top_bottom(session, y, session->full_rect.y1);
end_v = rect.y1;
break;
case guicom_scrollable_section_end:
always_give_to_user = 1;
break;
}
if (give_to_user){
{
GUI_Section *section = session->sections;
i32 max_v = 0;
i32 i = 0;
@ -622,6 +648,9 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){
}
}
session->absolute_rect = rect;
if (give_to_user){
rect.y0 -= scroll_v;
rect.y1 -= scroll_v;
@ -639,13 +668,17 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){
give_to_user = 0;
}
}
}
if (end_section){
gui_section_end_item(end_section, end_v);
}
if (y - scroll_v >= session->full_rect.y1){
give_to_user = 0;
}
return(give_to_user);
return(give_to_user || always_give_to_user);
}
#define NextHeader(h) ((GUI_Header*)((char*)(h) + (h)->size))