diff --git a/4coder_string.h b/4coder_string.h index c97215b8..cf23dc68 100644 --- a/4coder_string.h +++ b/4coder_string.h @@ -139,7 +139,10 @@ FCPP_LINK int str_to_int(char *s); FCPP_LINK int str_to_int(String s); FCPP_LINK int hexchar_to_int(char c); FCPP_LINK char int_to_hexchar(int c); -FCPP_LINK int hexstr_to_int(String s); +FCPP_LINK unsigned int hexstr_to_int(String s); + +FCPP_LINK bool color_to_hexstr(unsigned int color, String *s_out); +FCPP_LINK bool hexstr_to_color(String s, unsigned int *color); FCPP_LINK int copy_fast_unsafe(char *dest, char *src); FCPP_LINK void copy_fast_unsafe(char *dest, String src); @@ -810,9 +813,10 @@ int_to_hexchar(int x){ return (x<10)?((char)x+'0'):((char)x+'a'-10); } -FCPP_LINK int +FCPP_LINK unsigned int hexstr_to_int(String str){ - int x, i; + unsigned int x; + int i; if (str.size == 0){ x = 0; } @@ -826,6 +830,51 @@ hexstr_to_int(String str){ return x; } +FCPP_LINK bool +color_to_hexstr(unsigned int color, String *s){ + bool result = 0; + int i; + + if (s->memory_size == 7 || s->memory_size == 8){ + result = 1; + s->size = 6; + s->str[6] = 0; + color = color & 0x00FFFFFF; + for (i = 5; i >= 0; --i){ + s->str[i] = int_to_hexchar(color & 0xF); + color >>= 4; + } + } + else if (s->memory_size > 8){ + result = 1; + s->size = 8; + s->str[8] = 0; + for (i = 7; i >= 0; --i){ + s->str[i] = int_to_hexchar(color & 0xF); + color >>= 4; + } + } + return(result); +} + +FCPP_LINK bool +hexstr_to_color(String s, unsigned int *out){ + bool result = 0; + unsigned int color = 0; + if (s.size == 6){ + result = 1; + color = (unsigned int)hexstr_to_int(s); + color |= (0xFF << 24); + *out = color; + } + else if (s.size == 8){ + result = 1; + color = (unsigned int)hexstr_to_int(s); + *out = color; + } + return(result); +} + FCPP_LINK int copy_fast_unsafe(char *dest, char *src){ char *start = dest; diff --git a/4ed.cpp b/4ed.cpp index 6d9100a1..72276938 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -3947,22 +3947,6 @@ App_Step_Sig(app_step){ } } ProfileStart(frame_hook); - - ProfileStart(fill_gui_command_buffers); - { - Panel *panel, *used_panels; - View *view, *active_view; - - active_view = cmd->panel->view; - used_panels = &models->layout.used_sentinel; - for (dll_items(panel, used_panels)){ - view = panel->view; - if (step_file_view(system, view, active_view)){ - app_result.redraw = 1; - } - } - } - ProfileStart(fill_gui_command_buffers); // NOTE(allen): pass raw input to the panels ProfileStart(step); @@ -4005,17 +3989,28 @@ App_Step_Sig(app_step){ if (consumed_input[5]){ mouse_state.wheel = 0; } - + { Panel *panel, *used_panels; - View *view; + View *view, *active_view; b32 active; + Input_Summary input; + active_view = cmd->panel->view; used_panels = &models->layout.used_sentinel; for (dll_items(panel, used_panels)){ view = panel->view; active = (panel == cmd->panel); - Input_Summary input = (active)?(active_input):(dead_input); + input = (active)?(active_input):(dead_input); + if (step_file_view(system, view, active_view, input)){ + app_result.redraw = 1; + } + } + + for (dll_items(panel, used_panels)){ + view = panel->view; + active = (panel == cmd->panel); + input = (active)?(active_input):(dead_input); if (panel == mouse_panel && !mouse->out_of_window){ input.mouse = mouse_state; } diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index da88960a..9ef39f4f 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -98,6 +98,7 @@ struct View{ b8 import_export_check[64]; i32 import_file_id; i32 current_color_editing; + i32 color_cursor; // file stuff i32 font_advance; @@ -3664,13 +3665,14 @@ static Style_Color_Edit colors_to_edit[] = { }; internal i32 -step_file_view(System_Functions *system, View *view, View *active_view){ +step_file_view(System_Functions *system, View *view, View *active_view, Input_Summary input){ GUI_Target *target = &view->gui_target; Models *models = view->models; + Key_Summary keys = input.keys; f32 min_target_y = view->file_scroll.min_y; - gui_begin_top_level(target); + gui_begin_top_level(target, input); { gui_do_top_bar(target); @@ -3816,6 +3818,8 @@ step_file_view(System_Functions *system, View *view, View *active_view){ gui_get_scroll_vars(target, view->showing_ui, &view->gui_scroll); gui_begin_scrollable(target, view->showing_ui, view->gui_scroll, 9.f * view->font_height); + + i32 next_color_editing = view->current_color_editing; for (i = 0; i < ArrayCount(colors_to_edit); ++i){ edit_color = style_index_by_tag(&style->main, colors_to_edit[i].target); @@ -3825,14 +3829,64 @@ step_file_view(System_Functions *system, View *view, View *active_view){ back = style_index_by_tag(&style->main, colors_to_edit[i].back); if (gui_do_color_button(target, id, *fore, *back, colors_to_edit[i].text)){ - view->current_color_editing = i; + next_color_editing = i; + view->color_cursor = 0; } if (view->current_color_editing == i){ - // TODO(allen): color editor + GUI_Item_Update update = {0}; + char text_space[7]; + String text = make_fixed_width_string(text_space); + + color_to_hexstr(*edit_color, &text); + if (gui_do_text_with_cursor(target, view->color_cursor, text, &update)){ + b32 r = 0; + i32 j = 0; + + for (j = 0; j < keys.count; ++j){ + i16 key = keys.keys[j].keycode; + switch (key){ + case key_left: --view->color_cursor; r = 1; break; + case key_right: ++view->color_cursor; r = 1; break; + + case key_up: + if (next_color_editing > 0){ + --next_color_editing; + } + break; + + case key_down: + if (next_color_editing <= ArrayCount(colors_to_edit)-1){ + ++next_color_editing; + } + break; + + default: + if ((key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (key >= 'A' && key <= 'F')){ + text.str[view->color_cursor] = (char)key; + r = 1; + } + break; + } + + if (view->color_cursor < 0) view->color_cursor = 0; + if (view->color_cursor >= 6) view->color_cursor = 5; + } + + if (r){ + hexstr_to_color(text, edit_color); + gui_rollback(target, &update); + gui_do_text_with_cursor(target, view->color_cursor, text, 0); + } + } } } + if (view->current_color_editing != next_color_editing){ + view->current_color_editing = next_color_editing; + view->color_cursor = 0; + } + gui_end_scrollable(target); }break; } diff --git a/4ed_gui.cpp b/4ed_gui.cpp index de17c553..b14f4c04 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -140,6 +140,11 @@ struct GUI_Target{ GUI_Scroll_Vars scroll_updated; f32 delta; u32 scroll_id; + b32 has_keys; +}; + +struct GUI_Item_Update{ + i32 partition_point; }; struct GUI_Header{ @@ -170,6 +175,7 @@ enum GUI_Command_Type{ guicom_text_input, guicom_file_input, guicom_color_button, + guicom_text_with_cursor, guicom_file_option, guicom_fixed_option, guicom_button, @@ -215,6 +221,16 @@ gui_active_level(GUI_Target *target, GUI_id id){ return(level); } +internal void +gui_rollback(GUI_Target *target, GUI_Item_Update *update){ + target->push.pos = update->partition_point; +} + +internal void +gui_fill_item_update(GUI_Item_Update *update, GUI_Target *target, GUI_Header *h){ + update->partition_point = (i32)((char*)h - (char*)target->push.base); +} + internal void* gui_push_item(GUI_Target *target, void *item, i32 size){ void *dest = partition_allocate(&target->push, size); @@ -350,8 +366,9 @@ gui_end_serial_section(GUI_Target *target){ } internal void -gui_begin_top_level(GUI_Target *target){ +gui_begin_top_level(GUI_Target *target, Input_Summary input){ target->push.pos = 0; + target->has_keys = (input.keys.count > 0); } internal void @@ -376,6 +393,18 @@ gui_do_text_field(GUI_Target *target, String prompt, String text){ gui_push_string(target, h, text); } +internal b32 +gui_do_text_with_cursor(GUI_Target *target, i32 pos, String text, GUI_Item_Update *update){ + b32 result = 1; + GUI_Header *h = gui_push_simple_command(target, guicom_text_with_cursor); + gui_push_string(target, h, text); + gui_push_item(target, h, &pos, sizeof(i32)); + + result = target->has_keys; + gui_fill_item_update(update, target, h); + return(result); +} + internal b32 gui_do_text_input(GUI_Target *target, GUI_id id, void *out){ b32 result = 0; @@ -790,6 +819,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ scroll_v = 0; break; + case guicom_text_with_cursor: case guicom_text_field: give_to_user = 1; rect = gui_layout_fixed_h(session, y, session->line_height + 2); @@ -805,7 +835,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h){ case guicom_color_button: give_to_user = 1; - rect = gui_layout_fixed_h(session, y, session->line_height); + rect = gui_layout_fixed_h(session, y, session->line_height + 2); end_v = rect.y1; end_section = section; break;