From 468a7a33bcfec2cb4c177220e4bfb1023092ed8c Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 16 Jul 2018 20:21:22 -0700 Subject: [PATCH] Progress on GUI scrolling --- 4coder_API/types.h | 2 + 4coder_base_commands.cpp | 171 +++++++++++++++++++++------- 4coder_generated/command_metadata.h | 2 +- 4coder_ui_helper.cpp | 40 ++++++- 4ed.cpp | 75 ++++++------ 4ed_api_implementation.cpp | 20 +++- 4ed_math.h | 18 +++ 4ed_render_format.cpp | 14 +++ 4ed_view.cpp | 12 +- 4ed_view.h | 7 +- 4ed_view_ui.cpp | 108 +++++++++--------- 11 files changed, 308 insertions(+), 161 deletions(-) diff --git a/4coder_API/types.h b/4coder_API/types.h index 86c8879e..6ce9ab64 100644 --- a/4coder_API/types.h +++ b/4coder_API/types.h @@ -737,6 +737,8 @@ STRUCT UI_List{ STRUCT UI_Control{ UI_Item *items; int32_t count; + + i32_Rect bounding_box; }; /* diff --git a/4coder_base_commands.cpp b/4coder_base_commands.cpp index c0b876ae..7ff0297b 100644 --- a/4coder_base_commands.cpp +++ b/4coder_base_commands.cpp @@ -1509,16 +1509,27 @@ CUSTOM_DOC("Interactively switch to an open buffer.") int32_t line_height = (int32_t)view.line_height; int32_t block_height = line_height*2; + int32_t hot_buffer_id = 0; + int32_t item_index = 0; + Temp_Memory temp = begin_temp_memory(scratch); String text_field = push_string(scratch, 256); - Temp_Memory list_restore_point = begin_temp_memory(scratch); for(;;){ - end_temp_memory(list_restore_point); + Temp_Memory full_temp = begin_temp_memory(scratch); + + refresh_view(app, &view); + Mouse_State mouse_state = get_mouse_state(app); + int32_t mx = mouse_state.x - view.file_region.x0 + (int32_t)view.scroll_vars.scroll_x; + int32_t my = mouse_state.y - view.file_region.y0 + (int32_t)view.scroll_vars.scroll_y; int32_t y_pos = line_height; UI_List list = {0}; + int32_t item_index_counter = 0; UI_Item *highlighted_item = 0; + UI_Item *hot_item = 0; + UI_Item *hovered_item = 0; + int32_t option_item_count = 0; for (Buffer_Summary buffer = get_buffer_first(app, AccessAll); buffer.exists; get_buffer_next(app, &buffer, AccessAll)){ @@ -1543,17 +1554,39 @@ CUSTOM_DOC("Interactively switch to an open buffer.") item.user_data = (void*)buffer.buffer_id; item.activation_level = UIActivation_None; item.rectangle = item_rect; - if (highlighted_item == 0){ - item.activation_level = UIActivation_Hover; - UI_Item *item_ptr = ui_list_add_item(scratch, &list, item); + + UI_Item *item_ptr = ui_list_add_item(scratch, &list, item); + option_item_count += 1; + + if (item_rect.x0 <= mx && mx < item_rect.x1 && + item_rect.y0 <= my && my < item_rect.y1){ + hovered_item = item_ptr; + } + if (item_index_counter == item_index){ highlighted_item = item_ptr; } - else{ - ui_list_add_item(scratch, &list, item); + item_index_counter += 1; + if (buffer.buffer_id == hot_buffer_id){ + hot_item = item_ptr; } } } + if (hovered_item != 0){ + hovered_item->activation_level = UIActivation_Hover; + } + if (hot_item != 0){ + if (hot_item == hovered_item){ + hot_item->activation_level = UIActivation_Active; + } + else{ + hot_item->activation_level = UIActivation_Hover; + } + } + if (highlighted_item != 0){ + highlighted_item->activation_level = UIActivation_Active; + } + { i32_Rect item_rect = {0}; item_rect.x0 = x0; @@ -1566,6 +1599,7 @@ CUSTOM_DOC("Interactively switch to an open buffer.") item.type = UIType_TextField; item.query = push_string_copy(scratch, "Switch: "); item.string = text_field; + item.activation_level = UIActivation_Active; item.user_data = 0; item.rectangle = item_rect; ui_list_add_item(scratch, &list, item); @@ -1574,45 +1608,94 @@ CUSTOM_DOC("Interactively switch to an open buffer.") UI_Control control = ui_list_to_ui_control(scratch, &list); view_set_ui(app, &view, &control); - User_Input in = get_user_input(app, EventAll, EventOnEsc); - if (in.abort){ - goto done; - } - - UI_Item *activated_item = 0; - switch (in.type){ - case UserInputKey: - { - if (in.key.keycode == '\n' || in.key.keycode == '\t'){ - activated_item = highlighted_item; - } - else if (in.key.keycode == key_back){ - backspace_utf8(&text_field); - } - else{ - uint8_t character[4]; - uint32_t length = to_writable_character(in, character); - if (length > 0){ - append(&text_field, make_string(character, length)); - } - } - }break; + for (;;){ + bool32 needs_full_update = false; - case UserInputMouse: - { - if (in.mouse.press_l){ - int32_t mx = in.mouse.x - view.view_region.x0; - int32_t my = in.mouse.y - view.view_region.y0; - activated_item = ui_control_get_mouse_hit(&control, mx, my); - } - }break; - } - - if (activated_item != 0){ - int32_t buffer_id = (int32_t)activated_item->user_data; - view_set_buffer(app, &view, buffer_id, 0); - goto done; + User_Input in = get_user_input(app, EventAll, EventOnEsc); + if (in.abort){ + goto done; + } + + UI_Item *activated_item = 0; + switch (in.type){ + case UserInputKey: + { + if (in.key.keycode == '\n' || in.key.keycode == '\t'){ + activated_item = highlighted_item; + } + else if (in.key.keycode == key_back){ + backspace_utf8(&text_field); + needs_full_update = true; + item_index = 0; + } + else if (in.key.keycode == key_up || in.key.keycode == key_page_up){ + item_index = item_index - 1; + if (item_index < 0){ + item_index = 0; + } + needs_full_update = true; + } + else if (in.key.keycode == key_down || in.key.keycode == key_page_down){ + item_index = item_index + 1; + if (item_index > option_item_count - 1){ + item_index = option_item_count - 1; + } + needs_full_update = true; + } + else{ + uint8_t character[4]; + uint32_t length = to_writable_character(in, character); + if (length > 0){ + append(&text_field, make_string(character, length)); + needs_full_update = true; + item_index = 0; + } + } + }break; + + case UserInputMouse: + { + if (in.mouse.wheel != 0){ + GUI_Scroll_Vars scroll = view.scroll_vars; + scroll.target_y += in.mouse.wheel; + view_set_scroll(app, &view, scroll); + } + if (in.mouse.press_l || in.mouse.release_l){ + int32_t mx = in.mouse.x - view.file_region.x0; + int32_t my = in.mouse.y - view.file_region.y0; + UI_Item *clicked = ui_control_get_mouse_hit(&control, mx, my); + if (in.mouse.press_l){ + if (clicked != 0){ + hot_buffer_id = (int32_t)clicked->user_data; + } + } + if (in.mouse.release_l){ + if (clicked != 0){ + if (hot_buffer_id == (int32_t)clicked->user_data){ + activated_item = clicked; + } + } + hot_buffer_id = 0; + } + needs_full_update = true; + } + if (mx != in.mouse.x || my != in.mouse.y){ + needs_full_update = true; + } + }break; + } + + if (activated_item != 0){ + int32_t buffer_id = (int32_t)activated_item->user_data; + view_set_buffer(app, &view, buffer_id, 0); + goto done; + } + if (needs_full_update){ + goto full_update; + } } + full_update:; + end_temp_memory(full_temp); } done:; diff --git a/4coder_generated/command_metadata.h b/4coder_generated/command_metadata.h index 2635b215..c0d97573 100644 --- a/4coder_generated/command_metadata.h +++ b/4coder_generated/command_metadata.h @@ -307,7 +307,7 @@ static Command_Metadata fcoder_metacmd_table[185] = { { PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 42, 1062 }, { PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1492 }, { PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1339 }, -{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1625 }, +{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1708 }, { PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 49, 58 }, { PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 49, 74 }, { PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 49, 66 }, diff --git a/4coder_ui_helper.cpp b/4coder_ui_helper.cpp index 0de844a2..4db174ac 100644 --- a/4coder_ui_helper.cpp +++ b/4coder_ui_helper.cpp @@ -17,22 +17,50 @@ static UI_Control ui_list_to_ui_control(Partition *arena, UI_List *list){ UI_Control control = {0}; control.items = push_array(arena, UI_Item, list->count); + if (list->count > 0){ + control.bounding_box = list->first->fixed.rectangle; + } for (UI_Item_Node *node = list->first; node != 0; node = node->next){ control.items[control.count++] = node->fixed; + if (control.bounding_box.x0 > node->fixed.rectangle.x0){ + control.bounding_box.x0 = node->fixed.rectangle.x0; + } + if (control.bounding_box.x1 < node->fixed.rectangle.x1){ + control.bounding_box.x1 = node->fixed.rectangle.x1; + } + if (control.bounding_box.y0 > node->fixed.rectangle.y0){ + control.bounding_box.y0 = node->fixed.rectangle.y0; + } + if (control.bounding_box.y1 < node->fixed.rectangle.y1){ + control.bounding_box.y1 = node->fixed.rectangle.y1; + } } return(control); } +static void +ui_control_set_top(UI_Control *control, int32_t top_y){ + control->bounding_box.y0 = top_y; +} + +static void +ui_control_set_bottom(UI_Control *control, int32_t bottom_y){ + control->bounding_box.y1 = bottom_y; +} + static UI_Item* ui_control_get_mouse_hit(UI_Control *control, int32_t mx, int32_t my){ - int32_t count = control->count; - UI_Item *item = control->items + count - 1; - for (int32_t i = 0; i < count; ++i, item -= 1){ - i32_Rect r = item->rectangle; - if (r.x0 <= mx && mx < r.x1 && r.y0 <= my && my < r.y1){ - return(item); + if (control->bounding_box.x0 <= mx && mx < control->bounding_box.x1 && + control->bounding_box.y0 <= my && my < control->bounding_box.y1){ + int32_t count = control->count; + UI_Item *item = control->items + count - 1; + for (int32_t i = 0; i < count; ++i, item -= 1){ + i32_Rect r = item->rectangle; + if (r.x0 <= mx && mx < r.x1 && r.y0 <= my && my < r.y1){ + return(item); + } } } return(0); diff --git a/4ed.cpp b/4ed.cpp index 3c7c1cc0..60cb6127 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -1868,51 +1868,46 @@ App_Step_Sig(app_step){ b32 active = (panel == active_panel); Input_Summary summary = (active)?(active_input):(dead_input); - view->transient.changed_context_in_step = 0; + if (panel == mouse_panel && !input->mouse.out_of_window){ + summary.mouse = mouse_state; + } - if (view->transient.changed_context_in_step == 0){ - active = (panel == active_panel); - summary = (active)?(active_input):(dead_input); - if (panel == mouse_panel && !input->mouse.out_of_window){ - summary.mouse = mouse_state; - } - - b32 file_scroll = true; - GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos->scroll; - - i32 max_y = 0; - if (view->transient.ui_mode_counter == 0){ - max_y = view_compute_max_target_y(view); + GUI_Scroll_Vars *scroll_vars = 0; + i32 max_y = 0; + b32 file_scroll = false; + if (view->transient.ui_mode_counter == 0){ + scroll_vars = &view->transient.edit_pos->scroll; + max_y = view_compute_max_target_y(view); + file_scroll = true; + } + else{ + scroll_vars = &view->transient.ui_scroll; + i32 bottom = view->transient.ui_control.bounding_box.y1; + max_y = view_compute_max_target_y_from_bottom_y(view, (f32)bottom); + file_scroll = false; + } + + Input_Process_Result ip_result = do_step_file_view(system, view, models, panel->inner, active, &summary, *scroll_vars, max_y); + + if (ip_result.is_animating){ + app_result.animating = true; + } + if (ip_result.consumed_l){ + consume_input(&vars->available_input, Input_MouseLeftButton, "file view step"); + } + if (ip_result.consumed_r){ + consume_input(&vars->available_input, Input_MouseRightButton, "file view step"); + } + + if (memcmp(scroll_vars, &ip_result.scroll, sizeof(*scroll_vars)) != 0){ + if (file_scroll){ + view_set_scroll(system, view, ip_result.scroll); } else{ -#if 0 - max_y = view->transient.gui_max_y; -#endif + *scroll_vars = ip_result.scroll; } - - Input_Process_Result ip_result = do_step_file_view(system, view, models, panel->inner, active, &summary, *scroll_vars, view->transient.scroll_region, max_y); - - if (ip_result.is_animating){ - app_result.animating = 1; - } - if (ip_result.consumed_l){ - consume_input(&vars->available_input, Input_MouseLeftButton, "file view step"); - } - if (ip_result.consumed_r){ - consume_input(&vars->available_input, Input_MouseRightButton, "file view step"); - } - - if (memcmp(scroll_vars, &ip_result.vars, sizeof(*scroll_vars)) != 0){ - if (file_scroll){ - view_set_scroll(system, view, ip_result.vars); - } - else{ - *scroll_vars = ip_result.vars; - } - } - - view->transient.scroll_region = ip_result.region; } + } } diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index bafbd4c3..3507fc57 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -86,7 +86,12 @@ fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Live view->view_region = vptr->transient.panel->inner; view->file_region = vptr->transient.file_region; - view->scroll_vars = vptr->transient.edit_pos->scroll; + if (vptr->transient.ui_mode_counter == 0){ + view->scroll_vars = vptr->transient.edit_pos->scroll; + } + else{ + view->scroll_vars = vptr->transient.ui_scroll; + } } } @@ -2001,7 +2006,12 @@ DOC_SEE(GUI_Scroll_Vars) Assert(file != 0); if (!file->is_loading){ result = true; - view_set_scroll(system, vptr, scroll); + if (vptr->transient.ui_mode_counter == 0){ + view_set_scroll(system, vptr, scroll); + } + else{ + vptr->transient.ui_scroll = scroll; + } fill_view_summary(system, view, vptr, cmd); } } @@ -2228,7 +2238,7 @@ View_Set_UI(Application_Links *app, View_Summary *view, UI_Control *control){ if (vptr->transient.ui_control.items != 0){ general_memory_free(general, vptr->transient.ui_control.items); } - vptr->transient.ui_control.count = 0; + memset(&vptr->transient.ui_control, 0, sizeof(vptr->transient.ui_control)); if (control->count > 0){ i32 memory_size = sizeof(UI_Item)*control->count; vptr->transient.ui_control.items = (UI_Item*)general_memory_allocate(general, memory_size); @@ -2240,9 +2250,7 @@ View_Set_UI(Application_Links *app, View_Summary *view, UI_Control *control){ return(false); } } - else{ - vptr->transient.ui_control.items = 0; - } + vptr->transient.ui_control.bounding_box = control->bounding_box; return(true); } return(false); diff --git a/4ed_math.h b/4ed_math.h index 9f3df328..e7995acc 100644 --- a/4ed_math.h +++ b/4ed_math.h @@ -657,5 +657,23 @@ fits_inside(i32_Rect rect, i32_Rect outer){ return(rect.x0 >= outer.x0 && rect.x1 <= outer.x1 && rect.y0 >= outer.y0 && rect.y1 <= outer.y1); } +static int32_t +interval_overlap(float a0, float a1, float b0, float b1){ + if (a0 <= b0 && b0 < a1 || + b0 <= a0 && a0 < b1){ + return(true); + } + return(false); +} + +static int32_t +rect_opverlap(f32_Rect a, f32_Rect b){ + if (interval_overlap(a.x0, a.x1, b.x0, b.x1) && + interval_overlap(a.y0, a.y1, b.y0, b.y1)){ + return(true); + } + return(false); +} + // BOTTOM diff --git a/4ed_render_format.cpp b/4ed_render_format.cpp index 776d95b3..e7284f11 100644 --- a/4ed_render_format.cpp +++ b/4ed_render_format.cpp @@ -74,6 +74,20 @@ draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){ draw_rectangle_outline(target, f32R(rect), color); } +internal void +draw_margin(Render_Target *target, f32_Rect outer, f32_Rect inner, u32 color){ + draw_rectangle(target, f32R(outer.x0, outer.y0, outer.x1, inner.y0), color); + draw_rectangle(target, f32R(outer.x0, inner.y1, outer.x1, outer.y1), color); + draw_rectangle(target, f32R(outer.x0, inner.y0, inner.x0, inner.y1), color); + draw_rectangle(target, f32R(inner.x1, inner.y0, outer.x1, inner.y1), color); +} + +inline void +draw_margin(Render_Target *target, f32_Rect outer, f32 width, u32 color){ + f32_Rect inner = get_inner_rect(outer, width); + draw_margin(target, outer, inner, color); +} + internal void draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){ draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color); diff --git a/4ed_view.cpp b/4ed_view.cpp index d5590f87..cfe3200c 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -138,6 +138,14 @@ view_cursor_limits(View *view){ return(limits); } +inline i32 +view_compute_max_target_y_from_bottom_y(View *view, f32 max_item_y){ + i32 line_height = view->transient.line_height; + f32 height = clamp_bottom((f32)line_height, view_height(view)); + f32 max_target_y = clamp_bottom(0.f, max_item_y - height*0.5f); + return(ceil32(max_target_y)); +} + inline i32 view_compute_max_target_y(View *view){ i32 line_height = view->transient.line_height; @@ -147,9 +155,7 @@ view_compute_max_target_y(View *view){ if (!file->settings.unwrapped_lines){ lowest_line = file->state.wrap_line_index[buffer->line_count]; } - f32 height = clamp_bottom((f32)line_height, view_height(view)); - f32 max_target_y = clamp_bottom(0.f, ((lowest_line + 0.5f)*line_height) - height*0.5f); - return(ceil32(max_target_y)); + return(view_compute_max_target_y_from_bottom_y(view, (lowest_line + 0.5f)*(f32)line_height)); } inline u32 diff --git a/4ed_view.h b/4ed_view.h index 2676c278..7e8704cb 100644 --- a/4ed_view.h +++ b/4ed_view.h @@ -48,6 +48,7 @@ struct View_Transient{ i32 ui_mode_counter; UI_Control ui_control; + GUI_Scroll_Vars ui_scroll; b32 hide_scrollbar; b32 hide_file_bar; @@ -184,14 +185,10 @@ struct View_Step_Result{ }; struct Input_Process_Result{ - GUI_Scroll_Vars vars; - i32_Rect region; + GUI_Scroll_Vars scroll; b32 is_animating; b32 consumed_l; b32 consumed_r; - - b32 has_max_y_suggestion; - i32 max_y; }; enum{ diff --git a/4ed_view_ui.cpp b/4ed_view_ui.cpp index ad585546..0a4958f5 100644 --- a/4ed_view_ui.cpp +++ b/4ed_view_ui.cpp @@ -146,13 +146,11 @@ global_const Style_Color_Edit colors_to_edit[] = { }; internal Input_Process_Result -do_step_file_view(System_Functions *system, View *view, Models *models, i32_Rect rect, b32 is_active, Input_Summary *user_input, GUI_Scroll_Vars vars, i32_Rect region, i32 max_y){ +do_step_file_view(System_Functions *system, View *view, Models *models, i32_Rect rect, b32 is_active, Input_Summary *user_input, GUI_Scroll_Vars scroll, i32 max_y){ + scroll.target_y = clamp(0, scroll.target_y, max_y); + Input_Process_Result result = {0}; - - vars.target_y = clamp(0, vars.target_y, max_y); - - result.vars = vars; - result.region = region; + result.scroll = scroll; i32 line_height = view->transient.line_height; @@ -166,8 +164,8 @@ do_step_file_view(System_Functions *system, View *view, Models *models, i32_Rect } if (user_input->mouse.wheel != 0){ - result.vars.target_y += user_input->mouse.wheel; - result.vars.target_y = clamp(0, result.vars.target_y, max_y); + result.scroll.target_y += user_input->mouse.wheel; + result.scroll.target_y = clamp(0, result.scroll.target_y, max_y); result.is_animating = true; } @@ -194,26 +192,23 @@ do_step_file_view(System_Functions *system, View *view, Models *models, i32_Rect target_y = clamp_bottom(0, floor32(cursor.y - height*.5f)); } - result.vars.target_y = target_y; - result.vars.scroll_y = (f32)target_y; - result.vars.prev_target_y = -1000; + result.scroll.target_y = target_y; + result.scroll.scroll_y = (f32)target_y; + result.scroll.prev_target_y = -1000; - result.vars.target_x = target_x; - result.vars.scroll_x = (f32)target_x; - result.vars.prev_target_x = -1000; + result.scroll.target_x = target_x; + result.scroll.scroll_x = (f32)target_x; + result.scroll.prev_target_x = -1000; } if (!file->is_loading && file->state.paste_effect.seconds_down > 0.f){ file->state.paste_effect.seconds_down -= user_input->dt; result.is_animating = true; } - - result.has_max_y_suggestion = true; - result.max_y = view_compute_max_target_y(view); } { - GUI_Scroll_Vars scroll_vars = result.vars; + GUI_Scroll_Vars scroll_vars = result.scroll; b32 is_new_target = (scroll_vars.target_x != scroll_vars.prev_target_x || scroll_vars.target_y != scroll_vars.prev_target_y); @@ -227,7 +222,7 @@ do_step_file_view(System_Functions *system, View *view, Models *models, i32_Rect scroll_vars.prev_target_x = scroll_vars.target_x; scroll_vars.prev_target_y = scroll_vars.target_y; - result.vars = scroll_vars; + result.scroll = scroll_vars; } return(result); @@ -398,46 +393,47 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc } } else{ + f32_Rect rect_f32 = f32R(rect); + i32 item_count = view->transient.ui_control.count; UI_Item *item = view->transient.ui_control.items; + GUI_Scroll_Vars scroll = view->transient.ui_scroll; for (i32 i = 0; i < item_count; ++i, item += 1){ - switch (item->type){ - case UIType_Option: - { - u32 back = style->main.back_color; - u32 margin = style_get_margin_color(item->activation_level, style); - u32 text_color = style->main.default_color; - u32 pop_color = style->main.file_info_style.pop2_color; - i32_Rect item_rect = item->rectangle; - item_rect.x0 += rect.x0; - item_rect.y0 += rect.y0; - item_rect.x1 += rect.x0; - item_rect.y1 += rect.y0; - i32_Rect inner = get_inner_rect(item_rect, 3); - draw_rectangle(target, inner, back); - draw_margin(target, item_rect, inner, margin); - i32 x = inner.x0 + 3; - i32 y = inner.y0 + line_height/2 - 1; - x = ceil32(draw_string(system, target, font_id, item->string, x, y, text_color)); - draw_string(system, target, font_id, item->status, x, y, pop_color); - }break; - - case UIType_TextField: - { - u32 back_color = style->main.margin_color; - u32 text1_color = style->main.default_color; - u32 text2_color = style->main.file_info_style.pop1_color; - i32_Rect item_rect = item->rectangle; - item_rect.x0 += rect.x0; - item_rect.y0 += rect.y0; - item_rect.x1 += rect.x0; - item_rect.y1 += rect.y0; - draw_rectangle(target, item_rect, back_color); - i32 x = item_rect.x0; - i32 y = item_rect.y0 + 2; - x = ceil32(draw_string(system, target, font_id, item->query, x, y, text2_color)); - draw_string(system, target, font_id, item->string, x, y, text1_color); - }break; + f32_Rect item_rect = f32R(item->rectangle); + item_rect.x0 += rect_f32.x0 - scroll.scroll_x; + item_rect.y0 += rect_f32.y0 - scroll.scroll_y; + item_rect.x1 += rect_f32.x0 - scroll.scroll_x; + item_rect.y1 += rect_f32.y0 - scroll.scroll_y; + + if (rect_opverlap(item_rect, rect_f32)){ + switch (item->type){ + case UIType_Option: + { + u32 back = style->main.back_color; + u32 margin_color = style_get_margin_color(item->activation_level, style); + u32 text_color = style->main.default_color; + u32 pop_color = style->main.file_info_style.pop2_color; + f32_Rect inner = get_inner_rect(item_rect, 3); + draw_rectangle(target, inner, back); + draw_margin(target, item_rect, inner, margin_color); + i32 x = (i32)inner.x0 + 3; + i32 y = (i32)inner.y0 + line_height/2 - 1; + x = ceil32(draw_string(system, target, font_id, item->string, x, y, text_color)); + draw_string(system, target, font_id, item->status, x, y, pop_color); + }break; + + case UIType_TextField: + { + u32 back_color = style->main.margin_color; + u32 text1_color = style->main.default_color; + u32 text2_color = style->main.file_info_style.pop1_color; + draw_rectangle(target, item_rect, back_color); + i32 x = (i32)item_rect.x0; + i32 y = (i32)item_rect.y0 + 2; + x = ceil32(draw_string(system, target, font_id, item->query, x, y, text2_color)); + draw_string(system, target, font_id, item->string, x, y, text1_color); + }break; + } } } }