got overlapped gui clipping working

master
Allen Webster 2016-04-26 17:09:41 -04:00
parent efc042af3e
commit 2e3262dd18
3 changed files with 98 additions and 73 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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;