From 2e3262dd180d81397dd17fd5551be62f213b1b7d Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 26 Apr 2016 17:09:41 -0400 Subject: [PATCH] got overlapped gui clipping working --- 4ed_file_view.cpp | 96 ++++++++++++++++++++++------------------ 4ed_gui.cpp | 69 ++++++++++++++++------------- 4ed_rendering_helper.cpp | 6 +++ 3 files changed, 98 insertions(+), 73 deletions(-) diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 8eb8305a..d09f8b01 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -3650,46 +3650,45 @@ step_file_view(System_Functions *system, View *view, b32 is_active){ if (view->showing_ui == VUI_None){ gui_begin_overlap(target); - do_widget(view, target); - - gui_begin_serial_section(target); { - 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 = 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 target_y = 0; + do_widget(view, target); - 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; - } + gui_begin_serial_section(target); + { + 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 = 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 target_y = 0; - if (cursor_y != old_cursor_y){ - if (cursor_y > old_cursor_y){ - cursor_y += view->font_height; - } - else{ - cursor_y -= view->font_height; - } - view->cursor = view_compute_cursor_from_xy(view, view->preferred_x, cursor_y); - } - } - - gui_begin_scrollable(target, view->showing_ui, view->file_scroll, delta); + 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; + } - gui_do_file(target); - - gui_end_scrollable(target); + if (cursor_y != old_cursor_y){ + if (cursor_y > old_cursor_y){ + cursor_y += view->font_height; + } + else{ + cursor_y -= view->font_height; + } + view->cursor = view_compute_cursor_from_xy(view, view->preferred_x, cursor_y); + } + } + + gui_begin_scrollable(target, view->showing_ui, view->file_scroll, delta); + gui_do_file(target); + gui_end_scrollable(target); + } + gui_end_serial_section(target); } - gui_end_serial_section(target); - gui_end_overlap(target); } else{ @@ -3705,7 +3704,7 @@ step_file_view(System_Functions *system, View *view, b32 is_active){ case IAct_Save_As: message = make_lit_string("Save As: "); break; case IAct_New: message = make_lit_string("New: "); break; } - + Exhaustive_File_Loop loop; Exhaustive_File_Info file_info; @@ -4071,7 +4070,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange, case guicom_file: { - f32 new_min_y = -(f32)(gui_session.clip_rect.y0 - gui_session.rect.y0); + f32 new_min_y = -(f32)(gui_session_get_eclipsed_y(&gui_session) - gui_session.rect.y0); f32 new_max_y = view_compute_max_target_y(view); view->gui_target.scroll_updated.min_y = new_min_y; @@ -4663,10 +4662,19 @@ do_render_file_view(System_Functions *system, Exchange *exchange, v = view_get_scroll_y(view); + i32_Rect clip_rect = rect; + draw_push_clip(target, clip_rect); + for (h = (GUI_Header*)gui_target->push.base; h->type; h = NextHeader(h)){ if (gui_interpret(&view->gui_target, &gui_session, h)){ + + if (gui_session.clip_y > clip_rect.y0){ + clip_rect.y0 = gui_session.clip_y; + draw_change_clip(target, clip_rect); + } + switch (h->type){ case guicom_top_bar: { @@ -4778,17 +4786,19 @@ do_render_file_view(System_Functions *system, Exchange *exchange, }break; case guicom_begin_scrollable_section: - { - target->push_clip(target, gui_session.absolute_rect); - }break; + clip_rect.x1 -= gui_session.scroll_bar_w; + draw_push_clip(target, clip_rect); + break; case guicom_end_scrollable_section: - { - target->pop_clip(target); - }break; + clip_rect.x1 += gui_session.scroll_bar_w; + draw_pop_clip(target); + break; } } } + + draw_pop_clip(target); return(result); diff --git a/4ed_gui.cpp b/4ed_gui.cpp index 03772ff8..03e602f7 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -428,6 +428,8 @@ internal void gui_begin_scrollable(GUI_Target *target, u32 scroll_id, GUI_Scroll_Vars scroll_vars, f32 delta){ GUI_Header *h; + gui_begin_serial_section(target); + target->delta = delta; h = gui_push_simple_command(target, guicom_scrollable); @@ -444,6 +446,7 @@ gui_begin_scrollable(GUI_Target *target, u32 scroll_id, GUI_Scroll_Vars scroll_v internal void gui_end_scrollable(GUI_Target *target){ gui_push_simple_command(target, guicom_end_scrollable_section); + gui_end_serial_section(target); } internal void @@ -453,17 +456,16 @@ gui_activate_scrolling(GUI_Target *target){ struct GUI_Section{ b32 overlapped; - i32 max_v, v; + i32 max_v, v, top_v; }; 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 clip_y; i32 line_height; i32 scroll_bar_w; @@ -479,6 +481,26 @@ struct GUI_Session{ #define GUIScrollbarWidth 16 +internal i32 +gui_session_get_eclipsed_y(GUI_Session *session){ + GUI_Section *section = session->sections; + i32 count = session->t + 1, i; + i32 max_v = 0; + for (i = 0; i < count; ++i, ++section){ + if (section->overlapped){ + max_v = Max(max_v, section->max_v); + } + } + max_v = Max(max_v, session->sections[count-1].top_v); + return(max_v); +} + +internal i32 +gui_session_get_current_top(GUI_Session *session){ + i32 result = session->sections[session->t].top_v; + return(result); +} + internal void gui_session_init(GUI_Session *session, i32_Rect full_rect, i32 line_height){ GUI_Section *section; @@ -498,7 +520,9 @@ gui_section_end_item(GUI_Section *section, i32 v){ if (!section->overlapped){ section->v = v; } - section->max_v = v; + if (section->max_v < v){ + section->max_v = v; + } } inline i32_Rect @@ -608,6 +632,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ new_section->overlapped = 1; new_section->v = y; new_section->max_v = y; + new_section->top_v = y; break; case guicom_end_overlap: @@ -625,6 +650,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ new_section->overlapped = 0; new_section->v = y; new_section->max_v = y; + new_section->top_v = y; break; case guicom_end_serial: @@ -732,59 +758,42 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ case guicom_end_scrollable_section: always_give_to_user = 1; - session->suggested_min_y = -(f32)(session->clip_rect.y0 - session->rect.y0); + session->suggested_min_y = -(f32)(gui_session_get_eclipsed_y(session) - gui_session_get_current_top(session)); session->suggested_max_y = (f32)(session->scrollable_items_bottom - session->full_rect.y1 * .5f); if (session->suggested_max_y < 0){ session->suggested_max_y = 0; } break; } - + if (do_layout){ - GUI_Section *section = session->sections; - i32 max_v = 0; - i32 i = 0; - - session->absolute_rect = rect; - if (give_to_user){ - for (i = 0; i <= session->t; ++i, ++section){ - if (section->overlapped){ - max_v = Max(max_v, section->max_v); - } - } - if (session->is_scrollable){ session->scrollable_items_bottom = Max(session->scrollable_items_bottom, rect.y1); } - + 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; } else{ 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; } } - + + session->clip_y = gui_session_get_eclipsed_y(session); + return(give_to_user || always_give_to_user); } diff --git a/4ed_rendering_helper.cpp b/4ed_rendering_helper.cpp index c2c1d756..7df86de4 100644 --- a/4ed_rendering_helper.cpp +++ b/4ed_rendering_helper.cpp @@ -19,6 +19,12 @@ draw_pop_clip(Render_Target *target){ target->pop_clip(target); } +inline void +draw_change_clip(Render_Target *target, i32_Rect clip_box){ + target->pop_clip(target); + target->push_clip(target, clip_box); +} + internal void begin_render_section(Render_Target *target, System_Functions *system){ Font_Set *font_set = &target->font_set;