Răsfoiți Sursa

Port to 1.18 Forge + Fabric

Jared 3 ani în urmă
părinte
comite
b0ebaace2f
95 a modificat fișierele cu 3396 adăugiri și 1470 ștergeri
  1. 992 0
      .editorconfig
  2. 15 0
      .gitattributes
  3. 9 9
      .gitignore
  4. 44 0
      Common/build.gradle
  5. 10 0
      Common/src/main/java/com/blamejared/controlling/ControllingCommon.java
  6. 35 0
      Common/src/main/java/com/blamejared/controlling/api/DisplayMode.java
  7. 11 0
      Common/src/main/java/com/blamejared/controlling/api/ISort.java
  8. 1 2
      Common/src/main/java/com/blamejared/controlling/api/SearchType.java
  9. 40 0
      Common/src/main/java/com/blamejared/controlling/api/SortOrder.java
  10. 13 0
      Common/src/main/java/com/blamejared/controlling/api/events/IKeyEntryListenersEvent.java
  11. 18 0
      Common/src/main/java/com/blamejared/controlling/api/events/IKeyEntryMouseClickedEvent.java
  12. 18 0
      Common/src/main/java/com/blamejared/controlling/api/events/IKeyEntryMouseReleasedEvent.java
  13. 29 0
      Common/src/main/java/com/blamejared/controlling/api/events/IKeyEntryRenderEvent.java
  14. 35 0
      Common/src/main/java/com/blamejared/controlling/client/CustomList.java
  15. 73 0
      Common/src/main/java/com/blamejared/controlling/client/FancyCheckbox.java
  16. 144 0
      Common/src/main/java/com/blamejared/controlling/client/FreeKeysList.java
  17. 294 0
      Common/src/main/java/com/blamejared/controlling/client/NewKeyBindsList.java
  18. 396 0
      Common/src/main/java/com/blamejared/controlling/client/NewKeyBindsScreen.java
  19. 17 0
      Common/src/main/java/com/blamejared/controlling/mixin/AccessInputConstantsKey.java
  20. 17 0
      Common/src/main/java/com/blamejared/controlling/mixin/AccessKeyBindsScreen.java
  21. 14 0
      Common/src/main/java/com/blamejared/controlling/mixin/AccessKeyMapping.java
  22. 13 0
      Common/src/main/java/com/blamejared/controlling/mixin/AccessOptionsSubScreen.java
  23. 15 0
      Common/src/main/java/com/blamejared/controlling/mixin/AccessScreen.java
  24. 24 0
      Common/src/main/java/com/blamejared/controlling/platform/IEventHelper.java
  25. 25 0
      Common/src/main/java/com/blamejared/controlling/platform/IPlatformHelper.java
  26. 19 0
      Common/src/main/java/com/blamejared/controlling/platform/Services.java
  27. 0 0
      Common/src/main/resources/assets/controlling/lang/de_de.json
  28. 0 0
      Common/src/main/resources/assets/controlling/lang/en_ca.json
  29. 0 0
      Common/src/main/resources/assets/controlling/lang/en_pt.json
  30. 0 0
      Common/src/main/resources/assets/controlling/lang/en_ud.json
  31. 1 1
      Common/src/main/resources/assets/controlling/lang/en_us.json
  32. 0 0
      Common/src/main/resources/assets/controlling/lang/es_es.json
  33. 0 0
      Common/src/main/resources/assets/controlling/lang/fr_fr.json
  34. 0 0
      Common/src/main/resources/assets/controlling/lang/it_it.json
  35. 0 0
      Common/src/main/resources/assets/controlling/lang/ja_jp.json
  36. 0 0
      Common/src/main/resources/assets/controlling/lang/pl_pl.json
  37. 0 0
      Common/src/main/resources/assets/controlling/lang/pt_br.json
  38. 0 0
      Common/src/main/resources/assets/controlling/lang/ru_ru.json
  39. 0 0
      Common/src/main/resources/assets/controlling/lang/ta_in.json
  40. 0 0
      Common/src/main/resources/assets/controlling/lang/tr_tr.json
  41. 0 0
      Common/src/main/resources/assets/controlling/lang/uk_ua.json
  42. 0 0
      Common/src/main/resources/assets/controlling/lang/zh_cn.json
  43. 3 6
      Common/src/main/resources/assets/controlling/lang/zh_tw.json
  44. 6 0
      Common/src/main/resources/pack.mcmeta
  45. 135 0
      Fabric/build.gradle
  46. 20 0
      Fabric/src/main/java/com/blamejared/controlling/api/event/ControllingEvents.java
  47. 6 0
      Fabric/src/main/java/com/blamejared/controlling/api/event/IEventHandler.java
  48. 40 0
      Fabric/src/main/java/com/blamejared/controlling/api/event/KeyEntryListenersEvent.java
  49. 59 0
      Fabric/src/main/java/com/blamejared/controlling/api/event/KeyEntryMouseClickedEvent.java
  50. 58 0
      Fabric/src/main/java/com/blamejared/controlling/api/event/KeyEntryMouseReleasedEvent.java
  51. 96 0
      Fabric/src/main/java/com/blamejared/controlling/api/event/KeyEntryRenderEvent.java
  52. 33 0
      Fabric/src/main/java/com/blamejared/controlling/mixin/OpenGuiMixin.java
  53. 40 0
      Fabric/src/main/java/com/blamejared/controlling/platform/FabricEventHandler.java
  54. 5 0
      Fabric/src/main/java/com/blamejared/controlling/platform/FabricPlatformHelper.java
  55. 1 0
      Fabric/src/main/resources/META-INF/services/com.blamejared.controlling.platform.IEventHelper
  56. 1 0
      Fabric/src/main/resources/META-INF/services/com.blamejared.controlling.platform.IPlatformHelper
  57. 17 0
      Fabric/src/main/resources/controlling.mixins.json
  58. 21 0
      Fabric/src/main/resources/fabric.mod.json
  59. 166 0
      Forge/build.gradle
  60. 26 0
      Forge/src/main/java/com/blamejared/controlling/Controlling.java
  61. 40 0
      Forge/src/main/java/com/blamejared/controlling/api/events/KeyEntryListenersEvent.java
  62. 7 10
      Forge/src/main/java/com/blamejared/controlling/api/events/KeyEntryMouseClickedEvent.java
  63. 6 6
      Forge/src/main/java/com/blamejared/controlling/api/events/KeyEntryMouseReleasedEvent.java
  64. 9 9
      Forge/src/main/java/com/blamejared/controlling/api/events/KeyEntryRenderEvent.java
  65. 24 0
      Forge/src/main/java/com/blamejared/controlling/events/ClientEventHandler.java
  66. 48 0
      Forge/src/main/java/com/blamejared/controlling/platform/ForgeEventHandler.java
  67. 30 0
      Forge/src/main/java/com/blamejared/controlling/platform/ForgePlatformHelper.java
  68. 3 0
      Forge/src/main/resources/META-INF/accesstransformer.cfg
  69. 8 8
      Forge/src/main/resources/META-INF/mods.toml
  70. 1 0
      Forge/src/main/resources/META-INF/services/com.blamejared.controlling.platform.IEventHelper
  71. 1 0
      Forge/src/main/resources/META-INF/services/com.blamejared.controlling.platform.IPlatformHelper
  72. 16 0
      Forge/src/main/resources/controlling.mixins.json
  73. 1 1
      LICENSE
  74. 35 162
      build.gradle
  75. 29 2
      gradle.properties
  76. BIN
      gradle/wrapper/gradle-wrapper.jar
  77. 1 1
      gradle/wrapper/gradle-wrapper.properties
  78. 41 30
      gradlew
  79. 24 19
      gradlew.bat
  80. 17 0
      settings.gradle
  81. 0 44
      src/main/java/com/blamejared/controlling/Controlling.java
  82. 0 45
      src/main/java/com/blamejared/controlling/api/events/KeyEntryListenersEvent.java
  83. 0 33
      src/main/java/com/blamejared/controlling/client/gui/DisplayMode.java
  84. 0 67
      src/main/java/com/blamejared/controlling/client/gui/GuiCheckBox.java
  85. 0 28
      src/main/java/com/blamejared/controlling/client/gui/GuiCustomList.java
  86. 0 140
      src/main/java/com/blamejared/controlling/client/gui/GuiFreeKeysList.java
  87. 0 454
      src/main/java/com/blamejared/controlling/client/gui/GuiNewControls.java
  88. 0 284
      src/main/java/com/blamejared/controlling/client/gui/GuiNewKeyBindingList.java
  89. 0 8
      src/main/java/com/blamejared/controlling/client/gui/ISort.java
  90. 0 40
      src/main/java/com/blamejared/controlling/client/gui/SortOrder.java
  91. 0 22
      src/main/java/com/blamejared/controlling/events/ClientEventHandler.java
  92. 0 3
      src/main/resources/META-INF/accesstransformer.cfg
  93. 0 15
      src/main/resources/assets/controlling/lang/kk_kz.json
  94. 0 15
      src/main/resources/assets/controlling/lang/ko_kr.json
  95. 0 6
      src/main/resources/pack.mcmeta

+ 992 - 0
.editorconfig

@@ -0,0 +1,992 @@
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = false
+max_line_length = 120
+tab_width = 4
+ij_continuation_indent_size = 8
+ij_formatter_off_tag = @formatter:off
+ij_formatter_on_tag = @formatter:on
+ij_formatter_tags_enabled = false
+ij_smart_tabs = false
+ij_visual_guides = none
+ij_wrap_on_typing = false
+
+[*.java]
+ij_visual_guides = 120
+ij_java_align_consecutive_assignments = false
+ij_java_align_consecutive_variable_declarations = false
+ij_java_align_group_field_declarations = false
+ij_java_align_multiline_annotation_parameters = false
+ij_java_align_multiline_array_initializer_expression = false
+ij_java_align_multiline_assignment = false
+ij_java_align_multiline_binary_operation = false
+ij_java_align_multiline_chained_methods = false
+ij_java_align_multiline_extends_list = false
+ij_java_align_multiline_for = true
+ij_java_align_multiline_method_parentheses = false
+ij_java_align_multiline_parameters = true
+ij_java_align_multiline_parameters_in_calls = false
+ij_java_align_multiline_parenthesized_expression = false
+ij_java_align_multiline_records = true
+ij_java_align_multiline_resources = true
+ij_java_align_multiline_ternary_operation = false
+ij_java_align_multiline_text_blocks = false
+ij_java_align_multiline_throws_list = false
+ij_java_align_subsequent_simple_methods = false
+ij_java_align_throws_keyword = false
+ij_java_annotation_parameter_wrap = off
+ij_java_array_initializer_new_line_after_left_brace = false
+ij_java_array_initializer_right_brace_on_new_line = false
+ij_java_array_initializer_wrap = off
+ij_java_assert_statement_colon_on_next_line = false
+ij_java_assert_statement_wrap = off
+ij_java_assignment_wrap = off
+ij_java_binary_operation_sign_on_next_line = false
+ij_java_binary_operation_wrap = off
+ij_java_blank_lines_after_anonymous_class_header = 0
+ij_java_blank_lines_after_class_header = 1
+ij_java_blank_lines_after_imports = 1
+ij_java_blank_lines_after_package = 1
+ij_java_blank_lines_around_class = 1
+ij_java_blank_lines_around_field = 0
+ij_java_blank_lines_around_field_in_interface = 0
+ij_java_blank_lines_around_initializer = 0
+ij_java_blank_lines_around_method = 1
+ij_java_blank_lines_around_method_in_interface = 1
+ij_java_blank_lines_before_class_end = 1
+ij_java_blank_lines_before_imports = 1
+ij_java_blank_lines_before_method_body = 1
+ij_java_blank_lines_before_package = 0
+ij_java_block_brace_style = end_of_line
+ij_java_block_comment_at_first_column = true
+ij_java_call_parameters_new_line_after_left_paren = false
+ij_java_call_parameters_right_paren_on_new_line = false
+ij_java_call_parameters_wrap = off
+ij_java_case_statement_on_separate_line = true
+ij_java_catch_on_new_line = false
+ij_java_class_annotation_wrap = split_into_lines
+ij_java_class_brace_style = end_of_line
+ij_java_class_count_to_use_import_on_demand = 999
+ij_java_class_names_in_javadoc = 1
+ij_java_do_not_indent_top_level_class_members = false
+ij_java_do_not_wrap_after_single_annotation = false
+ij_java_do_while_brace_force = if_multiline
+ij_java_doc_add_blank_line_after_description = true
+ij_java_doc_add_blank_line_after_param_comments = true
+ij_java_doc_add_blank_line_after_return = true
+ij_java_doc_add_p_tag_on_empty_lines = false
+ij_java_doc_align_exception_comments = true
+ij_java_doc_align_param_comments = true
+ij_java_doc_do_not_wrap_if_one_line = false
+ij_java_doc_enable_formatting = true
+ij_java_doc_enable_leading_asterisks = true
+ij_java_doc_indent_on_continuation = false
+ij_java_doc_keep_empty_lines = true
+ij_java_doc_keep_empty_parameter_tag = true
+ij_java_doc_keep_empty_return_tag = true
+ij_java_doc_keep_empty_throws_tag = true
+ij_java_doc_keep_invalid_tags = true
+ij_java_doc_param_description_on_new_line = false
+ij_java_doc_preserve_line_breaks = false
+ij_java_doc_use_throws_not_exception_tag = true
+ij_java_else_on_new_line = false
+ij_java_entity_dd_suffix = EJB
+ij_java_entity_eb_suffix = Bean
+ij_java_entity_hi_suffix = Home
+ij_java_entity_lhi_prefix = Local
+ij_java_entity_lhi_suffix = Home
+ij_java_entity_li_prefix = Local
+ij_java_entity_pk_class = java.lang.String
+ij_java_entity_vo_suffix = VO
+ij_java_enum_constants_wrap = on_every_item
+ij_java_extends_keyword_wrap = off
+ij_java_extends_list_wrap = off
+ij_java_field_annotation_wrap = split_into_lines
+ij_java_finally_on_new_line = false
+ij_java_for_brace_force = if_multiline
+ij_java_for_statement_new_line_after_left_paren = false
+ij_java_for_statement_right_paren_on_new_line = false
+ij_java_for_statement_wrap = off
+ij_java_generate_final_locals = false
+ij_java_generate_final_parameters = false
+ij_java_if_brace_force = if_multiline
+ij_java_imports_layout = *,|,javax.**,java.**,|,$*
+ij_java_indent_case_from_switch = true
+ij_java_insert_inner_class_imports = false
+ij_java_insert_override_annotation = true
+ij_java_keep_blank_lines_before_right_brace = 2
+ij_java_keep_blank_lines_between_package_declaration_and_header = 2
+ij_java_keep_blank_lines_in_code = 2
+ij_java_keep_blank_lines_in_declarations = 2
+ij_java_keep_control_statement_in_one_line = false
+ij_java_keep_first_column_comment = false
+ij_java_keep_indents_on_empty_lines = true
+ij_java_keep_line_breaks = true
+ij_java_keep_multiple_expressions_in_one_line = false
+ij_java_keep_simple_blocks_in_one_line = false
+ij_java_keep_simple_classes_in_one_line = true
+ij_java_keep_simple_lambdas_in_one_line = true
+ij_java_keep_simple_methods_in_one_line = true
+ij_java_label_indent_absolute = false
+ij_java_label_indent_size = 0
+ij_java_lambda_brace_style = end_of_line
+ij_java_layout_static_imports_separately = true
+ij_java_line_comment_add_space = false
+ij_java_line_comment_at_first_column = true
+ij_java_message_dd_suffix = EJB
+ij_java_message_eb_suffix = Bean
+ij_java_method_annotation_wrap = split_into_lines
+ij_java_method_brace_style = end_of_line
+ij_java_method_call_chain_wrap = on_every_item
+ij_java_method_parameters_new_line_after_left_paren = false
+ij_java_method_parameters_right_paren_on_new_line = false
+ij_java_method_parameters_wrap = off
+ij_java_modifier_list_wrap = false
+ij_java_names_count_to_use_import_on_demand = 999
+ij_java_new_line_after_lparen_in_record_header = false
+ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
+ij_java_parameter_annotation_wrap = off
+ij_java_parentheses_expression_new_line_after_left_paren = false
+ij_java_parentheses_expression_right_paren_on_new_line = false
+ij_java_place_assignment_sign_on_next_line = false
+ij_java_prefer_longer_names = true
+ij_java_prefer_parameters_wrap = false
+ij_java_record_components_wrap = normal
+ij_java_repeat_synchronized = true
+ij_java_replace_instanceof_and_cast = false
+ij_java_replace_null_check = true
+ij_java_replace_sum_lambda_with_method_ref = true
+ij_java_resource_list_new_line_after_left_paren = false
+ij_java_resource_list_right_paren_on_new_line = false
+ij_java_resource_list_wrap = off
+ij_java_rparen_on_new_line_in_record_header = false
+ij_java_session_dd_suffix = EJB
+ij_java_session_eb_suffix = Bean
+ij_java_session_hi_suffix = Home
+ij_java_session_lhi_prefix = Local
+ij_java_session_lhi_suffix = Home
+ij_java_session_li_prefix = Local
+ij_java_session_si_suffix = Service
+ij_java_space_after_closing_angle_bracket_in_type_argument = true
+ij_java_space_after_colon = true
+ij_java_space_after_comma = true
+ij_java_space_after_comma_in_type_arguments = true
+ij_java_space_after_for_semicolon = true
+ij_java_space_after_quest = true
+ij_java_space_after_type_cast = true
+ij_java_space_before_annotation_array_initializer_left_brace = false
+ij_java_space_before_annotation_parameter_list = false
+ij_java_space_before_array_initializer_left_brace = true
+ij_java_space_before_catch_keyword = true
+ij_java_space_before_catch_left_brace = true
+ij_java_space_before_catch_parentheses = false
+ij_java_space_before_class_left_brace = true
+ij_java_space_before_colon = true
+ij_java_space_before_colon_in_foreach = true
+ij_java_space_before_comma = false
+ij_java_space_before_do_left_brace = true
+ij_java_space_before_else_keyword = true
+ij_java_space_before_else_left_brace = true
+ij_java_space_before_finally_keyword = true
+ij_java_space_before_finally_left_brace = true
+ij_java_space_before_for_left_brace = true
+ij_java_space_before_for_parentheses = false
+ij_java_space_before_for_semicolon = false
+ij_java_space_before_if_left_brace = true
+ij_java_space_before_if_parentheses = false
+ij_java_space_before_method_call_parentheses = false
+ij_java_space_before_method_left_brace = true
+ij_java_space_before_method_parentheses = false
+ij_java_space_before_opening_angle_bracket_in_type_parameter = false
+ij_java_space_before_quest = true
+ij_java_space_before_switch_left_brace = true
+ij_java_space_before_switch_parentheses = false
+ij_java_space_before_synchronized_left_brace = true
+ij_java_space_before_synchronized_parentheses = false
+ij_java_space_before_try_left_brace = true
+ij_java_space_before_try_parentheses = false
+ij_java_space_before_type_parameter_list = false
+ij_java_space_before_while_keyword = true
+ij_java_space_before_while_left_brace = true
+ij_java_space_before_while_parentheses = false
+ij_java_space_inside_one_line_enum_braces = false
+ij_java_space_within_empty_array_initializer_braces = false
+ij_java_space_within_empty_method_call_parentheses = false
+ij_java_space_within_empty_method_parentheses = false
+ij_java_spaces_around_additive_operators = true
+ij_java_spaces_around_assignment_operators = true
+ij_java_spaces_around_bitwise_operators = true
+ij_java_spaces_around_equality_operators = true
+ij_java_spaces_around_lambda_arrow = true
+ij_java_spaces_around_logical_operators = true
+ij_java_spaces_around_method_ref_dbl_colon = false
+ij_java_spaces_around_multiplicative_operators = true
+ij_java_spaces_around_relational_operators = true
+ij_java_spaces_around_shift_operators = true
+ij_java_spaces_around_type_bounds_in_type_parameters = true
+ij_java_spaces_around_unary_operator = false
+ij_java_spaces_within_angle_brackets = false
+ij_java_spaces_within_annotation_parentheses = false
+ij_java_spaces_within_array_initializer_braces = false
+ij_java_spaces_within_braces = false
+ij_java_spaces_within_brackets = false
+ij_java_spaces_within_cast_parentheses = false
+ij_java_spaces_within_catch_parentheses = false
+ij_java_spaces_within_for_parentheses = false
+ij_java_spaces_within_if_parentheses = false
+ij_java_spaces_within_method_call_parentheses = false
+ij_java_spaces_within_method_parentheses = false
+ij_java_spaces_within_parentheses = false
+ij_java_spaces_within_record_header = false
+ij_java_spaces_within_switch_parentheses = false
+ij_java_spaces_within_synchronized_parentheses = false
+ij_java_spaces_within_try_parentheses = false
+ij_java_spaces_within_while_parentheses = false
+ij_java_special_else_if_treatment = true
+ij_java_subclass_name_suffix = Impl
+ij_java_ternary_operation_signs_on_next_line = false
+ij_java_ternary_operation_wrap = off
+ij_java_test_name_suffix = Test
+ij_java_throws_keyword_wrap = off
+ij_java_throws_list_wrap = off
+ij_java_use_external_annotations = false
+ij_java_use_fq_class_names = false
+ij_java_use_relative_indents = false
+ij_java_use_single_class_imports = true
+ij_java_variable_annotation_wrap = off
+ij_java_visibility = public
+ij_java_while_brace_force = if_multiline
+ij_java_while_on_new_line = false
+ij_java_wrap_comments = false
+ij_java_wrap_first_method_in_call_chain = false
+ij_java_wrap_long_lines = false
+
+[*.nbtt]
+ij_continuation_indent_size = 4
+ij_visual_guides = 120
+ij_nbtt_keep_indents_on_empty_lines = false
+ij_nbtt_space_after_colon = true
+ij_nbtt_space_after_comma = true
+ij_nbtt_space_before_colon = true
+ij_nbtt_space_before_comma = false
+ij_nbtt_spaces_within_brackets = false
+ij_nbtt_spaces_within_parentheses = false
+
+[.editorconfig]
+ij_editorconfig_align_group_field_declarations = false
+ij_editorconfig_space_after_colon = false
+ij_editorconfig_space_after_comma = true
+ij_editorconfig_space_before_colon = false
+ij_editorconfig_space_before_comma = false
+ij_editorconfig_spaces_around_assignment_operators = true
+
+[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wadl,*.wsdd,*.wsdl,*.xjb,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
+ij_xml_align_attributes = true
+ij_xml_align_text = false
+ij_xml_attribute_wrap = normal
+ij_xml_block_comment_at_first_column = true
+ij_xml_keep_blank_lines = 2
+ij_xml_keep_indents_on_empty_lines = false
+ij_xml_keep_line_breaks = true
+ij_xml_keep_line_breaks_in_text = true
+ij_xml_keep_whitespaces = false
+ij_xml_keep_whitespaces_around_cdata = preserve
+ij_xml_keep_whitespaces_inside_cdata = false
+ij_xml_line_comment_at_first_column = true
+ij_xml_space_after_tag_name = false
+ij_xml_space_around_equals_in_attribute = false
+ij_xml_space_inside_empty_tag = false
+ij_xml_text_wrap = normal
+
+[{*.ats,*.ts}]
+ij_continuation_indent_size = 4
+ij_typescript_align_imports = false
+ij_typescript_align_multiline_array_initializer_expression = false
+ij_typescript_align_multiline_binary_operation = false
+ij_typescript_align_multiline_chained_methods = false
+ij_typescript_align_multiline_extends_list = false
+ij_typescript_align_multiline_for = true
+ij_typescript_align_multiline_parameters = true
+ij_typescript_align_multiline_parameters_in_calls = false
+ij_typescript_align_multiline_ternary_operation = false
+ij_typescript_align_object_properties = 0
+ij_typescript_align_union_types = false
+ij_typescript_align_var_statements = 0
+ij_typescript_array_initializer_new_line_after_left_brace = false
+ij_typescript_array_initializer_right_brace_on_new_line = false
+ij_typescript_array_initializer_wrap = off
+ij_typescript_assignment_wrap = off
+ij_typescript_binary_operation_sign_on_next_line = false
+ij_typescript_binary_operation_wrap = off
+ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
+ij_typescript_blank_lines_after_imports = 1
+ij_typescript_blank_lines_around_class = 1
+ij_typescript_blank_lines_around_field = 0
+ij_typescript_blank_lines_around_field_in_interface = 0
+ij_typescript_blank_lines_around_function = 1
+ij_typescript_blank_lines_around_method = 1
+ij_typescript_blank_lines_around_method_in_interface = 1
+ij_typescript_block_brace_style = end_of_line
+ij_typescript_call_parameters_new_line_after_left_paren = false
+ij_typescript_call_parameters_right_paren_on_new_line = false
+ij_typescript_call_parameters_wrap = off
+ij_typescript_catch_on_new_line = false
+ij_typescript_chained_call_dot_on_new_line = true
+ij_typescript_class_brace_style = end_of_line
+ij_typescript_comma_on_new_line = false
+ij_typescript_do_while_brace_force = never
+ij_typescript_else_on_new_line = false
+ij_typescript_enforce_trailing_comma = keep
+ij_typescript_extends_keyword_wrap = off
+ij_typescript_extends_list_wrap = off
+ij_typescript_field_prefix = _
+ij_typescript_file_name_style = relaxed
+ij_typescript_finally_on_new_line = false
+ij_typescript_for_brace_force = never
+ij_typescript_for_statement_new_line_after_left_paren = false
+ij_typescript_for_statement_right_paren_on_new_line = false
+ij_typescript_for_statement_wrap = off
+ij_typescript_force_quote_style = false
+ij_typescript_force_semicolon_style = false
+ij_typescript_function_expression_brace_style = end_of_line
+ij_typescript_if_brace_force = never
+ij_typescript_import_merge_members = global
+ij_typescript_import_prefer_absolute_path = global
+ij_typescript_import_sort_members = true
+ij_typescript_import_sort_module_name = false
+ij_typescript_import_use_node_resolution = true
+ij_typescript_imports_wrap = on_every_item
+ij_typescript_indent_case_from_switch = true
+ij_typescript_indent_chained_calls = true
+ij_typescript_indent_package_children = 0
+ij_typescript_jsdoc_include_types = false
+ij_typescript_jsx_attribute_value = braces
+ij_typescript_keep_blank_lines_in_code = 2
+ij_typescript_keep_first_column_comment = true
+ij_typescript_keep_indents_on_empty_lines = false
+ij_typescript_keep_line_breaks = true
+ij_typescript_keep_simple_blocks_in_one_line = false
+ij_typescript_keep_simple_methods_in_one_line = false
+ij_typescript_line_comment_add_space = true
+ij_typescript_line_comment_at_first_column = false
+ij_typescript_method_brace_style = end_of_line
+ij_typescript_method_call_chain_wrap = off
+ij_typescript_method_parameters_new_line_after_left_paren = false
+ij_typescript_method_parameters_right_paren_on_new_line = false
+ij_typescript_method_parameters_wrap = off
+ij_typescript_object_literal_wrap = on_every_item
+ij_typescript_parentheses_expression_new_line_after_left_paren = false
+ij_typescript_parentheses_expression_right_paren_on_new_line = false
+ij_typescript_place_assignment_sign_on_next_line = false
+ij_typescript_prefer_as_type_cast = false
+ij_typescript_prefer_explicit_types_function_expression_returns = false
+ij_typescript_prefer_explicit_types_function_returns = false
+ij_typescript_prefer_explicit_types_vars_fields = false
+ij_typescript_prefer_parameters_wrap = false
+ij_typescript_reformat_c_style_comments = false
+ij_typescript_space_after_colon = true
+ij_typescript_space_after_comma = true
+ij_typescript_space_after_dots_in_rest_parameter = false
+ij_typescript_space_after_generator_mult = true
+ij_typescript_space_after_property_colon = true
+ij_typescript_space_after_quest = true
+ij_typescript_space_after_type_colon = true
+ij_typescript_space_after_unary_not = false
+ij_typescript_space_before_async_arrow_lparen = true
+ij_typescript_space_before_catch_keyword = true
+ij_typescript_space_before_catch_left_brace = true
+ij_typescript_space_before_catch_parentheses = true
+ij_typescript_space_before_class_lbrace = true
+ij_typescript_space_before_class_left_brace = true
+ij_typescript_space_before_colon = true
+ij_typescript_space_before_comma = false
+ij_typescript_space_before_do_left_brace = true
+ij_typescript_space_before_else_keyword = true
+ij_typescript_space_before_else_left_brace = true
+ij_typescript_space_before_finally_keyword = true
+ij_typescript_space_before_finally_left_brace = true
+ij_typescript_space_before_for_left_brace = true
+ij_typescript_space_before_for_parentheses = true
+ij_typescript_space_before_for_semicolon = false
+ij_typescript_space_before_function_left_parenth = true
+ij_typescript_space_before_generator_mult = false
+ij_typescript_space_before_if_left_brace = true
+ij_typescript_space_before_if_parentheses = true
+ij_typescript_space_before_method_call_parentheses = false
+ij_typescript_space_before_method_left_brace = true
+ij_typescript_space_before_method_parentheses = false
+ij_typescript_space_before_property_colon = false
+ij_typescript_space_before_quest = true
+ij_typescript_space_before_switch_left_brace = true
+ij_typescript_space_before_switch_parentheses = true
+ij_typescript_space_before_try_left_brace = true
+ij_typescript_space_before_type_colon = false
+ij_typescript_space_before_unary_not = false
+ij_typescript_space_before_while_keyword = true
+ij_typescript_space_before_while_left_brace = true
+ij_typescript_space_before_while_parentheses = true
+ij_typescript_spaces_around_additive_operators = true
+ij_typescript_spaces_around_arrow_function_operator = true
+ij_typescript_spaces_around_assignment_operators = true
+ij_typescript_spaces_around_bitwise_operators = true
+ij_typescript_spaces_around_equality_operators = true
+ij_typescript_spaces_around_logical_operators = true
+ij_typescript_spaces_around_multiplicative_operators = true
+ij_typescript_spaces_around_relational_operators = true
+ij_typescript_spaces_around_shift_operators = true
+ij_typescript_spaces_around_unary_operator = false
+ij_typescript_spaces_within_array_initializer_brackets = false
+ij_typescript_spaces_within_brackets = false
+ij_typescript_spaces_within_catch_parentheses = false
+ij_typescript_spaces_within_for_parentheses = false
+ij_typescript_spaces_within_if_parentheses = false
+ij_typescript_spaces_within_imports = false
+ij_typescript_spaces_within_interpolation_expressions = false
+ij_typescript_spaces_within_method_call_parentheses = false
+ij_typescript_spaces_within_method_parentheses = false
+ij_typescript_spaces_within_object_literal_braces = false
+ij_typescript_spaces_within_object_type_braces = true
+ij_typescript_spaces_within_parentheses = false
+ij_typescript_spaces_within_switch_parentheses = false
+ij_typescript_spaces_within_type_assertion = false
+ij_typescript_spaces_within_union_types = true
+ij_typescript_spaces_within_while_parentheses = false
+ij_typescript_special_else_if_treatment = true
+ij_typescript_ternary_operation_signs_on_next_line = false
+ij_typescript_ternary_operation_wrap = off
+ij_typescript_union_types_wrap = on_every_item
+ij_typescript_use_chained_calls_group_indents = false
+ij_typescript_use_double_quotes = true
+ij_typescript_use_explicit_js_extension = global
+ij_typescript_use_path_mapping = always
+ij_typescript_use_public_modifier = false
+ij_typescript_use_semicolon_after_statement = true
+ij_typescript_var_declaration_wrap = normal
+ij_typescript_while_brace_force = never
+ij_typescript_while_on_new_line = false
+ij_typescript_wrap_comments = false
+
+[{*.bash,*.sh,*.zsh}]
+indent_size = 2
+tab_width = 2
+ij_shell_binary_ops_start_line = false
+ij_shell_keep_column_alignment_padding = false
+ij_shell_minify_program = false
+ij_shell_redirect_followed_by_space = false
+ij_shell_switch_cases_indented = false
+
+[{*.cjs,*.js}]
+ij_continuation_indent_size = 4
+ij_javascript_align_imports = false
+ij_javascript_align_multiline_array_initializer_expression = false
+ij_javascript_align_multiline_binary_operation = false
+ij_javascript_align_multiline_chained_methods = false
+ij_javascript_align_multiline_extends_list = false
+ij_javascript_align_multiline_for = true
+ij_javascript_align_multiline_parameters = true
+ij_javascript_align_multiline_parameters_in_calls = false
+ij_javascript_align_multiline_ternary_operation = false
+ij_javascript_align_object_properties = 0
+ij_javascript_align_union_types = false
+ij_javascript_align_var_statements = 0
+ij_javascript_array_initializer_new_line_after_left_brace = false
+ij_javascript_array_initializer_right_brace_on_new_line = false
+ij_javascript_array_initializer_wrap = off
+ij_javascript_assignment_wrap = off
+ij_javascript_binary_operation_sign_on_next_line = false
+ij_javascript_binary_operation_wrap = off
+ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
+ij_javascript_blank_lines_after_imports = 1
+ij_javascript_blank_lines_around_class = 1
+ij_javascript_blank_lines_around_field = 0
+ij_javascript_blank_lines_around_function = 1
+ij_javascript_blank_lines_around_method = 1
+ij_javascript_block_brace_style = end_of_line
+ij_javascript_call_parameters_new_line_after_left_paren = false
+ij_javascript_call_parameters_right_paren_on_new_line = false
+ij_javascript_call_parameters_wrap = off
+ij_javascript_catch_on_new_line = false
+ij_javascript_chained_call_dot_on_new_line = true
+ij_javascript_class_brace_style = end_of_line
+ij_javascript_comma_on_new_line = false
+ij_javascript_do_while_brace_force = never
+ij_javascript_else_on_new_line = false
+ij_javascript_enforce_trailing_comma = keep
+ij_javascript_extends_keyword_wrap = off
+ij_javascript_extends_list_wrap = off
+ij_javascript_field_prefix = _
+ij_javascript_file_name_style = relaxed
+ij_javascript_finally_on_new_line = false
+ij_javascript_for_brace_force = never
+ij_javascript_for_statement_new_line_after_left_paren = false
+ij_javascript_for_statement_right_paren_on_new_line = false
+ij_javascript_for_statement_wrap = off
+ij_javascript_force_quote_style = false
+ij_javascript_force_semicolon_style = false
+ij_javascript_function_expression_brace_style = end_of_line
+ij_javascript_if_brace_force = never
+ij_javascript_import_merge_members = global
+ij_javascript_import_prefer_absolute_path = global
+ij_javascript_import_sort_members = true
+ij_javascript_import_sort_module_name = false
+ij_javascript_import_use_node_resolution = true
+ij_javascript_imports_wrap = on_every_item
+ij_javascript_indent_case_from_switch = true
+ij_javascript_indent_chained_calls = true
+ij_javascript_indent_package_children = 0
+ij_javascript_jsx_attribute_value = braces
+ij_javascript_keep_blank_lines_in_code = 2
+ij_javascript_keep_first_column_comment = true
+ij_javascript_keep_indents_on_empty_lines = false
+ij_javascript_keep_line_breaks = true
+ij_javascript_keep_simple_blocks_in_one_line = false
+ij_javascript_keep_simple_methods_in_one_line = false
+ij_javascript_line_comment_add_space = true
+ij_javascript_line_comment_at_first_column = false
+ij_javascript_method_brace_style = end_of_line
+ij_javascript_method_call_chain_wrap = off
+ij_javascript_method_parameters_new_line_after_left_paren = false
+ij_javascript_method_parameters_right_paren_on_new_line = false
+ij_javascript_method_parameters_wrap = off
+ij_javascript_object_literal_wrap = on_every_item
+ij_javascript_parentheses_expression_new_line_after_left_paren = false
+ij_javascript_parentheses_expression_right_paren_on_new_line = false
+ij_javascript_place_assignment_sign_on_next_line = false
+ij_javascript_prefer_as_type_cast = false
+ij_javascript_prefer_explicit_types_function_expression_returns = false
+ij_javascript_prefer_explicit_types_function_returns = false
+ij_javascript_prefer_explicit_types_vars_fields = false
+ij_javascript_prefer_parameters_wrap = false
+ij_javascript_reformat_c_style_comments = false
+ij_javascript_space_after_colon = true
+ij_javascript_space_after_comma = true
+ij_javascript_space_after_dots_in_rest_parameter = false
+ij_javascript_space_after_generator_mult = true
+ij_javascript_space_after_property_colon = true
+ij_javascript_space_after_quest = true
+ij_javascript_space_after_type_colon = true
+ij_javascript_space_after_unary_not = false
+ij_javascript_space_before_async_arrow_lparen = true
+ij_javascript_space_before_catch_keyword = true
+ij_javascript_space_before_catch_left_brace = true
+ij_javascript_space_before_catch_parentheses = true
+ij_javascript_space_before_class_lbrace = true
+ij_javascript_space_before_class_left_brace = true
+ij_javascript_space_before_colon = true
+ij_javascript_space_before_comma = false
+ij_javascript_space_before_do_left_brace = true
+ij_javascript_space_before_else_keyword = true
+ij_javascript_space_before_else_left_brace = true
+ij_javascript_space_before_finally_keyword = true
+ij_javascript_space_before_finally_left_brace = true
+ij_javascript_space_before_for_left_brace = true
+ij_javascript_space_before_for_parentheses = true
+ij_javascript_space_before_for_semicolon = false
+ij_javascript_space_before_function_left_parenth = true
+ij_javascript_space_before_generator_mult = false
+ij_javascript_space_before_if_left_brace = true
+ij_javascript_space_before_if_parentheses = true
+ij_javascript_space_before_method_call_parentheses = false
+ij_javascript_space_before_method_left_brace = true
+ij_javascript_space_before_method_parentheses = false
+ij_javascript_space_before_property_colon = false
+ij_javascript_space_before_quest = true
+ij_javascript_space_before_switch_left_brace = true
+ij_javascript_space_before_switch_parentheses = true
+ij_javascript_space_before_try_left_brace = true
+ij_javascript_space_before_type_colon = false
+ij_javascript_space_before_unary_not = false
+ij_javascript_space_before_while_keyword = true
+ij_javascript_space_before_while_left_brace = true
+ij_javascript_space_before_while_parentheses = true
+ij_javascript_spaces_around_additive_operators = true
+ij_javascript_spaces_around_arrow_function_operator = true
+ij_javascript_spaces_around_assignment_operators = true
+ij_javascript_spaces_around_bitwise_operators = true
+ij_javascript_spaces_around_equality_operators = true
+ij_javascript_spaces_around_logical_operators = true
+ij_javascript_spaces_around_multiplicative_operators = true
+ij_javascript_spaces_around_relational_operators = true
+ij_javascript_spaces_around_shift_operators = true
+ij_javascript_spaces_around_unary_operator = false
+ij_javascript_spaces_within_array_initializer_brackets = false
+ij_javascript_spaces_within_brackets = false
+ij_javascript_spaces_within_catch_parentheses = false
+ij_javascript_spaces_within_for_parentheses = false
+ij_javascript_spaces_within_if_parentheses = false
+ij_javascript_spaces_within_imports = false
+ij_javascript_spaces_within_interpolation_expressions = false
+ij_javascript_spaces_within_method_call_parentheses = false
+ij_javascript_spaces_within_method_parentheses = false
+ij_javascript_spaces_within_object_literal_braces = false
+ij_javascript_spaces_within_object_type_braces = true
+ij_javascript_spaces_within_parentheses = false
+ij_javascript_spaces_within_switch_parentheses = false
+ij_javascript_spaces_within_type_assertion = false
+ij_javascript_spaces_within_union_types = true
+ij_javascript_spaces_within_while_parentheses = false
+ij_javascript_special_else_if_treatment = true
+ij_javascript_ternary_operation_signs_on_next_line = false
+ij_javascript_ternary_operation_wrap = off
+ij_javascript_union_types_wrap = on_every_item
+ij_javascript_use_chained_calls_group_indents = false
+ij_javascript_use_double_quotes = true
+ij_javascript_use_explicit_js_extension = global
+ij_javascript_use_path_mapping = always
+ij_javascript_use_public_modifier = false
+ij_javascript_use_semicolon_after_statement = true
+ij_javascript_var_declaration_wrap = normal
+ij_javascript_while_brace_force = never
+ij_javascript_while_on_new_line = false
+ij_javascript_wrap_comments = false
+
+[{*.comp,*.frag,*.fsh,*.geom,*.glsl,*.shader,*.tesc,*.tese,*.vert,*.vsh}]
+ij_glsl_keep_indents_on_empty_lines = false
+
+[{*.ft,*.vm,*.vsl}]
+ij_vtl_keep_indents_on_empty_lines = false
+
+[{*.gant,*.gradle,*.groovy,*.gy}]
+ij_groovy_align_group_field_declarations = false
+ij_groovy_align_multiline_array_initializer_expression = false
+ij_groovy_align_multiline_assignment = false
+ij_groovy_align_multiline_binary_operation = false
+ij_groovy_align_multiline_chained_methods = false
+ij_groovy_align_multiline_extends_list = false
+ij_groovy_align_multiline_for = true
+ij_groovy_align_multiline_list_or_map = true
+ij_groovy_align_multiline_method_parentheses = false
+ij_groovy_align_multiline_parameters = true
+ij_groovy_align_multiline_parameters_in_calls = false
+ij_groovy_align_multiline_resources = true
+ij_groovy_align_multiline_ternary_operation = false
+ij_groovy_align_multiline_throws_list = false
+ij_groovy_align_named_args_in_map = true
+ij_groovy_align_throws_keyword = false
+ij_groovy_array_initializer_new_line_after_left_brace = false
+ij_groovy_array_initializer_right_brace_on_new_line = false
+ij_groovy_array_initializer_wrap = off
+ij_groovy_assert_statement_wrap = off
+ij_groovy_assignment_wrap = off
+ij_groovy_binary_operation_wrap = off
+ij_groovy_blank_lines_after_class_header = 0
+ij_groovy_blank_lines_after_imports = 1
+ij_groovy_blank_lines_after_package = 1
+ij_groovy_blank_lines_around_class = 1
+ij_groovy_blank_lines_around_field = 0
+ij_groovy_blank_lines_around_field_in_interface = 0
+ij_groovy_blank_lines_around_method = 1
+ij_groovy_blank_lines_around_method_in_interface = 1
+ij_groovy_blank_lines_before_imports = 1
+ij_groovy_blank_lines_before_method_body = 0
+ij_groovy_blank_lines_before_package = 0
+ij_groovy_block_brace_style = end_of_line
+ij_groovy_block_comment_at_first_column = true
+ij_groovy_call_parameters_new_line_after_left_paren = false
+ij_groovy_call_parameters_right_paren_on_new_line = false
+ij_groovy_call_parameters_wrap = off
+ij_groovy_catch_on_new_line = false
+ij_groovy_class_annotation_wrap = split_into_lines
+ij_groovy_class_brace_style = end_of_line
+ij_groovy_class_count_to_use_import_on_demand = 5
+ij_groovy_do_while_brace_force = never
+ij_groovy_else_on_new_line = false
+ij_groovy_enum_constants_wrap = off
+ij_groovy_extends_keyword_wrap = off
+ij_groovy_extends_list_wrap = off
+ij_groovy_field_annotation_wrap = split_into_lines
+ij_groovy_finally_on_new_line = false
+ij_groovy_for_brace_force = never
+ij_groovy_for_statement_new_line_after_left_paren = false
+ij_groovy_for_statement_right_paren_on_new_line = false
+ij_groovy_for_statement_wrap = off
+ij_groovy_if_brace_force = never
+ij_groovy_import_annotation_wrap = 2
+ij_groovy_imports_layout = *,|,javax.**,java.**,|,$*
+ij_groovy_indent_case_from_switch = true
+ij_groovy_indent_label_blocks = true
+ij_groovy_insert_inner_class_imports = false
+ij_groovy_keep_blank_lines_before_right_brace = 2
+ij_groovy_keep_blank_lines_in_code = 2
+ij_groovy_keep_blank_lines_in_declarations = 2
+ij_groovy_keep_control_statement_in_one_line = true
+ij_groovy_keep_first_column_comment = true
+ij_groovy_keep_indents_on_empty_lines = false
+ij_groovy_keep_line_breaks = true
+ij_groovy_keep_multiple_expressions_in_one_line = false
+ij_groovy_keep_simple_blocks_in_one_line = false
+ij_groovy_keep_simple_classes_in_one_line = true
+ij_groovy_keep_simple_lambdas_in_one_line = true
+ij_groovy_keep_simple_methods_in_one_line = true
+ij_groovy_label_indent_absolute = false
+ij_groovy_label_indent_size = 0
+ij_groovy_lambda_brace_style = end_of_line
+ij_groovy_layout_static_imports_separately = true
+ij_groovy_line_comment_add_space = false
+ij_groovy_line_comment_at_first_column = true
+ij_groovy_method_annotation_wrap = split_into_lines
+ij_groovy_method_brace_style = end_of_line
+ij_groovy_method_call_chain_wrap = off
+ij_groovy_method_parameters_new_line_after_left_paren = false
+ij_groovy_method_parameters_right_paren_on_new_line = false
+ij_groovy_method_parameters_wrap = off
+ij_groovy_modifier_list_wrap = false
+ij_groovy_names_count_to_use_import_on_demand = 3
+ij_groovy_parameter_annotation_wrap = off
+ij_groovy_parentheses_expression_new_line_after_left_paren = false
+ij_groovy_parentheses_expression_right_paren_on_new_line = false
+ij_groovy_prefer_parameters_wrap = false
+ij_groovy_resource_list_new_line_after_left_paren = false
+ij_groovy_resource_list_right_paren_on_new_line = false
+ij_groovy_resource_list_wrap = off
+ij_groovy_space_after_assert_separator = true
+ij_groovy_space_after_colon = true
+ij_groovy_space_after_comma = true
+ij_groovy_space_after_comma_in_type_arguments = true
+ij_groovy_space_after_for_semicolon = true
+ij_groovy_space_after_quest = true
+ij_groovy_space_after_type_cast = true
+ij_groovy_space_before_annotation_parameter_list = false
+ij_groovy_space_before_array_initializer_left_brace = true
+ij_groovy_space_before_assert_separator = false
+ij_groovy_space_before_catch_keyword = true
+ij_groovy_space_before_catch_left_brace = true
+ij_groovy_space_before_catch_parentheses = true
+ij_groovy_space_before_class_left_brace = true
+ij_groovy_space_before_closure_left_brace = true
+ij_groovy_space_before_colon = true
+ij_groovy_space_before_comma = false
+ij_groovy_space_before_do_left_brace = true
+ij_groovy_space_before_else_keyword = true
+ij_groovy_space_before_else_left_brace = true
+ij_groovy_space_before_finally_keyword = true
+ij_groovy_space_before_finally_left_brace = true
+ij_groovy_space_before_for_left_brace = true
+ij_groovy_space_before_for_parentheses = true
+ij_groovy_space_before_for_semicolon = false
+ij_groovy_space_before_if_left_brace = true
+ij_groovy_space_before_if_parentheses = true
+ij_groovy_space_before_method_call_parentheses = false
+ij_groovy_space_before_method_left_brace = true
+ij_groovy_space_before_method_parentheses = false
+ij_groovy_space_before_quest = true
+ij_groovy_space_before_switch_left_brace = true
+ij_groovy_space_before_switch_parentheses = true
+ij_groovy_space_before_synchronized_left_brace = true
+ij_groovy_space_before_synchronized_parentheses = true
+ij_groovy_space_before_try_left_brace = true
+ij_groovy_space_before_try_parentheses = true
+ij_groovy_space_before_while_keyword = true
+ij_groovy_space_before_while_left_brace = true
+ij_groovy_space_before_while_parentheses = true
+ij_groovy_space_in_named_argument = true
+ij_groovy_space_in_named_argument_before_colon = false
+ij_groovy_space_within_empty_array_initializer_braces = false
+ij_groovy_space_within_empty_method_call_parentheses = false
+ij_groovy_spaces_around_additive_operators = true
+ij_groovy_spaces_around_assignment_operators = true
+ij_groovy_spaces_around_bitwise_operators = true
+ij_groovy_spaces_around_equality_operators = true
+ij_groovy_spaces_around_lambda_arrow = true
+ij_groovy_spaces_around_logical_operators = true
+ij_groovy_spaces_around_multiplicative_operators = true
+ij_groovy_spaces_around_regex_operators = true
+ij_groovy_spaces_around_relational_operators = true
+ij_groovy_spaces_around_shift_operators = true
+ij_groovy_spaces_within_annotation_parentheses = false
+ij_groovy_spaces_within_array_initializer_braces = false
+ij_groovy_spaces_within_braces = true
+ij_groovy_spaces_within_brackets = false
+ij_groovy_spaces_within_cast_parentheses = false
+ij_groovy_spaces_within_catch_parentheses = false
+ij_groovy_spaces_within_for_parentheses = false
+ij_groovy_spaces_within_gstring_injection_braces = false
+ij_groovy_spaces_within_if_parentheses = false
+ij_groovy_spaces_within_list_or_map = false
+ij_groovy_spaces_within_method_call_parentheses = false
+ij_groovy_spaces_within_method_parentheses = false
+ij_groovy_spaces_within_parentheses = false
+ij_groovy_spaces_within_switch_parentheses = false
+ij_groovy_spaces_within_synchronized_parentheses = false
+ij_groovy_spaces_within_try_parentheses = false
+ij_groovy_spaces_within_tuple_expression = false
+ij_groovy_spaces_within_while_parentheses = false
+ij_groovy_special_else_if_treatment = true
+ij_groovy_ternary_operation_wrap = off
+ij_groovy_throws_keyword_wrap = off
+ij_groovy_throws_list_wrap = off
+ij_groovy_use_flying_geese_braces = false
+ij_groovy_use_fq_class_names = false
+ij_groovy_use_fq_class_names_in_javadoc = true
+ij_groovy_use_relative_indents = false
+ij_groovy_use_single_class_imports = true
+ij_groovy_variable_annotation_wrap = off
+ij_groovy_while_brace_force = never
+ij_groovy_while_on_new_line = false
+ij_groovy_wrap_long_lines = false
+
+[{*.gradle.kts,*.kt,*.kts,*.main.kts}]
+ij_kotlin_align_in_columns_case_branch = false
+ij_kotlin_align_multiline_binary_operation = false
+ij_kotlin_align_multiline_extends_list = false
+ij_kotlin_align_multiline_method_parentheses = false
+ij_kotlin_align_multiline_parameters = true
+ij_kotlin_align_multiline_parameters_in_calls = false
+ij_kotlin_allow_trailing_comma = false
+ij_kotlin_allow_trailing_comma_on_call_site = false
+ij_kotlin_assignment_wrap = off
+ij_kotlin_blank_lines_after_class_header = 0
+ij_kotlin_blank_lines_around_block_when_branches = 0
+ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
+ij_kotlin_block_comment_at_first_column = true
+ij_kotlin_call_parameters_new_line_after_left_paren = false
+ij_kotlin_call_parameters_right_paren_on_new_line = false
+ij_kotlin_call_parameters_wrap = off
+ij_kotlin_catch_on_new_line = false
+ij_kotlin_class_annotation_wrap = split_into_lines
+ij_kotlin_continuation_indent_for_chained_calls = true
+ij_kotlin_continuation_indent_for_expression_bodies = true
+ij_kotlin_continuation_indent_in_argument_lists = true
+ij_kotlin_continuation_indent_in_elvis = true
+ij_kotlin_continuation_indent_in_if_conditions = true
+ij_kotlin_continuation_indent_in_parameter_lists = true
+ij_kotlin_continuation_indent_in_supertype_lists = true
+ij_kotlin_else_on_new_line = false
+ij_kotlin_enum_constants_wrap = off
+ij_kotlin_extends_list_wrap = off
+ij_kotlin_field_annotation_wrap = split_into_lines
+ij_kotlin_finally_on_new_line = false
+ij_kotlin_if_rparen_on_new_line = false
+ij_kotlin_import_nested_classes = false
+ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
+ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
+ij_kotlin_keep_blank_lines_before_right_brace = 2
+ij_kotlin_keep_blank_lines_in_code = 2
+ij_kotlin_keep_blank_lines_in_declarations = 2
+ij_kotlin_keep_first_column_comment = true
+ij_kotlin_keep_indents_on_empty_lines = false
+ij_kotlin_keep_line_breaks = true
+ij_kotlin_lbrace_on_next_line = false
+ij_kotlin_line_comment_add_space = false
+ij_kotlin_line_comment_at_first_column = true
+ij_kotlin_method_annotation_wrap = split_into_lines
+ij_kotlin_method_call_chain_wrap = off
+ij_kotlin_method_parameters_new_line_after_left_paren = false
+ij_kotlin_method_parameters_right_paren_on_new_line = false
+ij_kotlin_method_parameters_wrap = off
+ij_kotlin_name_count_to_use_star_import = 5
+ij_kotlin_name_count_to_use_star_import_for_members = 3
+ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.**
+ij_kotlin_parameter_annotation_wrap = off
+ij_kotlin_space_after_comma = true
+ij_kotlin_space_after_extend_colon = true
+ij_kotlin_space_after_type_colon = true
+ij_kotlin_space_before_catch_parentheses = true
+ij_kotlin_space_before_comma = false
+ij_kotlin_space_before_extend_colon = true
+ij_kotlin_space_before_for_parentheses = true
+ij_kotlin_space_before_if_parentheses = true
+ij_kotlin_space_before_lambda_arrow = true
+ij_kotlin_space_before_type_colon = false
+ij_kotlin_space_before_when_parentheses = true
+ij_kotlin_space_before_while_parentheses = true
+ij_kotlin_spaces_around_additive_operators = true
+ij_kotlin_spaces_around_assignment_operators = true
+ij_kotlin_spaces_around_equality_operators = true
+ij_kotlin_spaces_around_function_type_arrow = true
+ij_kotlin_spaces_around_logical_operators = true
+ij_kotlin_spaces_around_multiplicative_operators = true
+ij_kotlin_spaces_around_range = false
+ij_kotlin_spaces_around_relational_operators = true
+ij_kotlin_spaces_around_unary_operator = false
+ij_kotlin_spaces_around_when_arrow = true
+ij_kotlin_variable_annotation_wrap = off
+ij_kotlin_while_on_new_line = false
+ij_kotlin_wrap_elvis_expressions = 1
+ij_kotlin_wrap_expression_body_functions = 0
+ij_kotlin_wrap_first_method_in_call_chain = false
+
+[{*.graphqlconfig,*.har,*.jsb2,*.jsb3,*.json,*.mcmeta,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config,mcmod.info,pack.mcmeta}]
+indent_size = 2
+ij_visual_guides = 120
+ij_json_keep_blank_lines_in_code = 0
+ij_json_keep_indents_on_empty_lines = false
+ij_json_keep_line_breaks = true
+ij_json_space_after_colon = true
+ij_json_space_after_comma = true
+ij_json_space_before_colon = true
+ij_json_space_before_comma = false
+ij_json_spaces_within_braces = false
+ij_json_spaces_within_brackets = false
+ij_json_wrap_long_lines = false
+
+[{*.htm,*.html,*.sht,*.shtm,*.shtml}]
+ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
+ij_html_align_attributes = true
+ij_html_align_text = false
+ij_html_attribute_wrap = normal
+ij_html_block_comment_at_first_column = true
+ij_html_do_not_align_children_of_min_lines = 0
+ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
+ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot
+ij_html_enforce_quotes = false
+ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var
+ij_html_keep_blank_lines = 2
+ij_html_keep_indents_on_empty_lines = false
+ij_html_keep_line_breaks = true
+ij_html_keep_line_breaks_in_text = true
+ij_html_keep_whitespaces = false
+ij_html_keep_whitespaces_inside = span,pre,textarea
+ij_html_line_comment_at_first_column = true
+ij_html_new_line_after_last_attribute = never
+ij_html_new_line_before_first_attribute = never
+ij_html_quote_style = double
+ij_html_remove_new_line_before_tags = br
+ij_html_space_after_tag_name = false
+ij_html_space_around_equality_in_attribute = false
+ij_html_space_inside_empty_tag = false
+ij_html_text_wrap = normal
+ij_html_uniform_ident = false
+
+[{*.jsf,*.jsp,*.jspf,*.tag,*.tagf,*.xjsp}]
+ij_jsp_jsp_prefer_comma_separated_import_list = false
+ij_jsp_keep_indents_on_empty_lines = false
+
+[{*.jspx,*.tagx}]
+ij_jspx_keep_indents_on_empty_lines = false
+
+[{*.markdown,*.md}]
+ij_visual_guides = 120
+ij_markdown_force_one_space_after_blockquote_symbol = true
+ij_markdown_force_one_space_after_header_symbol = true
+ij_markdown_force_one_space_after_list_bullet = true
+ij_markdown_force_one_space_between_words = true
+ij_markdown_keep_indents_on_empty_lines = false
+ij_markdown_max_lines_around_block_elements = 1
+ij_markdown_max_lines_around_header = 1
+ij_markdown_max_lines_between_paragraphs = 1
+ij_markdown_min_lines_around_block_elements = 1
+ij_markdown_min_lines_around_header = 1
+ij_markdown_min_lines_between_paragraphs = 1
+
+[{*.properties,spring.handlers,spring.schemas}]
+ij_properties_align_group_field_declarations = false
+ij_properties_keep_blank_lines = false
+ij_properties_key_value_delimiter = equals
+ij_properties_spaces_around_key_value_delimiter = false
+
+[{*.yaml,*.yml}]
+indent_size = 2
+ij_yaml_align_values_properties = do_not_align
+ij_yaml_autoinsert_sequence_marker = true
+ij_yaml_block_mapping_on_new_line = false
+ij_yaml_indent_sequence_value = true
+ij_yaml_keep_indents_on_empty_lines = false
+ij_yaml_keep_line_breaks = true
+ij_yaml_sequence_on_new_line = false
+ij_yaml_space_before_colon = false
+ij_yaml_spaces_within_braces = true
+ij_yaml_spaces_within_brackets = true

+ 15 - 0
.gitattributes

@@ -0,0 +1,15 @@
+* text eol=lf
+*.bat text eol=crlf
+*.patch text eol=lf
+*.java text eol=lf
+*.gradle text eol=crlf
+*.png binary
+*.gif binary
+*.exe binary
+*.dll binary
+*.jar binary
+*.lzma binary
+*.zip binary
+*.pyd binary
+*.cfg text eol=lf
+*.jks binary

+ 9 - 9
.gitignore

@@ -3,22 +3,22 @@
 # Package Files #
 *.war
 *.ear
-/build
-/eclipse
-/bin
-/out
+build
+eclipse
+bin
+out
 
 *.classpath
 *.project
-/.gradle
-/.settings
-/.idea
+.gradle
+.settings
+.idea
 *.iml
 *.ipr
 *.iws
-/.metadata/*
+.metadata/*
 *.eml
-/run/
+run/
 usernamecache.json
 *.stackdump
 secrets.json

+ 44 - 0
Common/build.gradle

@@ -0,0 +1,44 @@
+import com.blamejared.modtemplate.Utils
+
+buildscript {
+    repositories {
+        maven {
+            name = "BlameJared"
+            url = 'https://maven.blamejared.com'
+        }
+        maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
+    }
+    dependencies {
+        classpath group: 'com.blamejared', name: 'ModTemplate', version: '2.+', changing: true
+    }
+}
+plugins {
+    id('java')
+    id('org.spongepowered.gradle.vanilla') version '0.2.1-SNAPSHOT'
+}
+
+apply plugin: 'com.blamejared.modtemplate'
+
+import com.blamejared.modtemplate.Utils
+
+archivesBaseName = "${mod_name}-common-${minecraft_version}"
+version = Utils.updatingVersion(mod_version)
+
+minecraft {
+    version(minecraft_version)
+    runs {   
+        if (project.hasProperty('common_runs_enabled') ? project.findProperty('common_runs_enabled').toBoolean() : true) {
+        
+            server(project.hasProperty('common_server_run_name') ? project.findProperty('common_server_run_name') : 'vanilla_server') {
+                workingDirectory(this.file("run"))
+            }
+            client(project.hasProperty('common_client_run_name') ? project.findProperty('common_client_run_name') : 'vanilla_client') {
+                workingDirectory(this.file("run"))
+            }
+        }
+    }
+}
+
+dependencies {
+     compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.4'
+}

+ 10 - 0
Common/src/main/java/com/blamejared/controlling/ControllingCommon.java

@@ -0,0 +1,10 @@
+package com.blamejared.controlling;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class ControllingCommon {
+    
+    public static final Logger LOG = LogManager.getLogger("controlling");
+    
+}

+ 35 - 0
Common/src/main/java/com/blamejared/controlling/api/DisplayMode.java

@@ -0,0 +1,35 @@
+package com.blamejared.controlling.api;
+
+import com.blamejared.controlling.client.NewKeyBindsList;
+import com.blamejared.controlling.mixin.AccessKeyMapping;
+import net.minecraft.client.KeyMapping;
+import net.minecraft.client.Minecraft;
+
+import java.util.function.Predicate;
+
+public enum DisplayMode {
+    ALL(keyEntry -> true), NONE(keyEntry -> keyEntry.getKeybinding().isUnbound()), CONFLICTING(keyEntry -> {
+        
+        for(KeyMapping key : Minecraft.getInstance().options.keyMappings) {
+            if(!key.getName().equals(keyEntry.getKeybinding().getName()) && !key.isUnbound()) {
+                if(((AccessKeyMapping) key).getKey().getValue() == ((AccessKeyMapping) keyEntry.getKeybinding()).getKey().getValue()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    });
+    
+    
+    private final Predicate<NewKeyBindsList.KeyEntry> predicate;
+    
+    DisplayMode(Predicate<NewKeyBindsList.KeyEntry> predicate) {
+        
+        this.predicate = predicate;
+    }
+    
+    public Predicate<NewKeyBindsList.KeyEntry> getPredicate() {
+        
+        return predicate;
+    }
+}

+ 11 - 0
Common/src/main/java/com/blamejared/controlling/api/ISort.java

@@ -0,0 +1,11 @@
+package com.blamejared.controlling.api;
+
+import com.blamejared.controlling.client.NewKeyBindsList;
+
+import java.util.List;
+
+public interface ISort {
+    
+    void sort(List<NewKeyBindsList.Entry> entries);
+    
+}

+ 1 - 2
src/main/java/com/blamejared/controlling/client/gui/SearchType.java → Common/src/main/java/com/blamejared/controlling/api/SearchType.java

@@ -1,5 +1,4 @@
-package com.blamejared.controlling.client.gui;
-
+package com.blamejared.controlling.api;
 
 public enum SearchType {
     NAME, KEY, CATEGORY;

+ 40 - 0
Common/src/main/java/com/blamejared/controlling/api/SortOrder.java

@@ -0,0 +1,40 @@
+package com.blamejared.controlling.api;
+
+import com.blamejared.controlling.client.NewKeyBindsList;
+import net.minecraft.client.resources.language.I18n;
+
+import java.util.Comparator;
+import java.util.List;
+
+public enum SortOrder {
+    NONE(entries -> {
+    }), AZ(entries -> entries.sort(Comparator.comparing(o -> ((NewKeyBindsList.KeyEntry) o).getKeyDesc()))), ZA(entries -> {
+        entries.sort((o1, o2) -> ((NewKeyBindsList.KeyEntry) o2).getKeyDesc().compareTo(((NewKeyBindsList.KeyEntry) o1).getKeyDesc()));
+    });
+    
+    private final ISort sorter;
+    
+    SortOrder(ISort sorter) {
+        
+        this.sorter = sorter;
+    }
+    
+    public SortOrder cycle() {
+        
+        return SortOrder.values()[(this.ordinal() + 1) % SortOrder.values().length];
+    }
+    
+    public void sort(List<NewKeyBindsList.Entry> list) {
+        
+        this.sorter.sort(list);
+    }
+    
+    public String getName() {
+        
+        return switch(this) {
+            case NONE -> I18n.get("options.sortNone");
+            case AZ -> I18n.get("options.sortAZ");
+            case ZA -> I18n.get("options.sortZA");
+        };
+    }
+}

+ 13 - 0
Common/src/main/java/com/blamejared/controlling/api/events/IKeyEntryListenersEvent.java

@@ -0,0 +1,13 @@
+package com.blamejared.controlling.api.events;
+
+import com.blamejared.controlling.client.NewKeyBindsList;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+
+import java.util.List;
+
+public interface IKeyEntryListenersEvent {
+    
+    List<GuiEventListener> getListeners();
+    
+    NewKeyBindsList.KeyEntry getEntry();
+}

+ 18 - 0
Common/src/main/java/com/blamejared/controlling/api/events/IKeyEntryMouseClickedEvent.java

@@ -0,0 +1,18 @@
+package com.blamejared.controlling.api.events;
+
+import com.blamejared.controlling.client.NewKeyBindsList;
+
+public interface IKeyEntryMouseClickedEvent {
+    
+    NewKeyBindsList.KeyEntry getEntry();
+    
+    double getMouseX();
+    
+    double getMouseY();
+    
+    int getButtonId();
+    
+    boolean isHandled();
+    
+    void setHandled(boolean handled);
+}

+ 18 - 0
Common/src/main/java/com/blamejared/controlling/api/events/IKeyEntryMouseReleasedEvent.java

@@ -0,0 +1,18 @@
+package com.blamejared.controlling.api.events;
+
+import com.blamejared.controlling.client.NewKeyBindsList;
+
+public interface IKeyEntryMouseReleasedEvent {
+    
+    NewKeyBindsList.KeyEntry getEntry();
+    
+    double getMouseX();
+    
+    double getMouseY();
+    
+    int getButtonId();
+    
+    boolean isHandled();
+    
+    void setHandled(boolean handled);
+}

+ 29 - 0
Common/src/main/java/com/blamejared/controlling/api/events/IKeyEntryRenderEvent.java

@@ -0,0 +1,29 @@
+package com.blamejared.controlling.api.events;
+
+import com.blamejared.controlling.client.NewKeyBindsList;
+import com.mojang.blaze3d.vertex.PoseStack;
+
+public interface IKeyEntryRenderEvent {
+    
+    NewKeyBindsList.KeyEntry getEntry();
+    
+    PoseStack getStack();
+    
+    int getSlotIndex();
+    
+    int getY();
+    
+    int getX();
+    
+    int getRowLeft();
+    
+    int getRowWidth();
+    
+    int getMouseX();
+    
+    int getMouseY();
+    
+    boolean isHovered();
+    
+    float getPartialTicks();
+}

+ 35 - 0
Common/src/main/java/com/blamejared/controlling/client/CustomList.java

@@ -0,0 +1,35 @@
+package com.blamejared.controlling.client;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.screens.controls.KeyBindsList;
+import net.minecraft.client.gui.screens.controls.KeyBindsScreen;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CustomList extends KeyBindsList {
+    
+    public List<Entry> allEntries;
+    
+    public CustomList(KeyBindsScreen controls, Minecraft mcIn) {
+        
+        super(controls, mcIn);
+    }
+    
+    public List<Entry> getAllEntries() {
+        
+        return allEntries;
+    }
+    
+    @Override
+    protected int addEntry(Entry ent) {
+        
+        if(allEntries == null) {
+            allEntries = new ArrayList<>();
+        }
+        allEntries.add(ent);
+        this.children().add(ent);
+        return this.children().size() - 1;
+    }
+    
+}

+ 73 - 0
Common/src/main/java/com/blamejared/controlling/client/FancyCheckbox.java

@@ -0,0 +1,73 @@
+package com.blamejared.controlling.client;
+
+import com.mojang.blaze3d.platform.GlStateManager;
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.components.AbstractButton;
+import net.minecraft.client.gui.narration.NarratedElementType;
+import net.minecraft.client.gui.narration.NarrationElementOutput;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.util.Mth;
+
+public class FancyCheckbox extends AbstractButton {
+    
+    private static final ResourceLocation TEXTURE = new ResourceLocation("textures/gui/checkbox.png");
+    private static final int TEXT_COLOR = 14737632;
+    private boolean selected;
+    private final OnPress pressFunction;
+    
+    public FancyCheckbox(int x, int y, int width, int height, Component label, boolean selected, OnPress pressFunction) {
+        super(x, y, Minecraft.getInstance().font.width(label) + 2 + width, height, label);
+        this.selected = selected;
+        this.pressFunction = pressFunction;
+    }
+    
+    public void onPress() {
+        this.selected = !this.selected;
+        if(pressFunction != null) {
+            pressFunction.onPress(this);
+        }
+    }
+    
+    public void selected(boolean selected) {
+        this.selected = selected;
+    }
+    
+    public boolean selected() {
+        return this.selected;
+    }
+    
+    public void updateNarration(NarrationElementOutput elementOutput) {
+        elementOutput.add(NarratedElementType.TITLE, this.createNarrationMessage());
+        if(this.active) {
+            if(this.isFocused()) {
+                elementOutput.add(NarratedElementType.USAGE, new TranslatableComponent("narration.checkbox.usage.focused"));
+            } else {
+                elementOutput.add(NarratedElementType.USAGE, new TranslatableComponent("narration.checkbox.usage.hovered"));
+            }
+        }
+        
+    }
+    
+    public void renderButton(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
+        Minecraft mc = Minecraft.getInstance();
+        RenderSystem.setShaderTexture(0, TEXTURE);
+        RenderSystem.enableDepthTest();
+        RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
+        RenderSystem.enableBlend();
+        RenderSystem.defaultBlendFunc();
+        RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
+        blit(stack, this.x, this.y, this.isHoveredOrFocused() ? 11 : 0.0F, this.selected ? 11 : 0.0F, 11, this.height, (int) (64f * (11f / 20f)), (int) (64f * (11f / 20f)));
+        this.renderBg(stack, mc, mouseX, mouseY);
+        drawString(stack, mc.font, this.getMessage(), this.x + 11 + 2, this.y + (this.height - 8) / 2, TEXT_COLOR | Mth.ceil(this.alpha * 255.0F) << 24);
+        
+    }
+    
+    public interface OnPress {
+        
+        void onPress(FancyCheckbox button);
+    }
+}

+ 144 - 0
Common/src/main/java/com/blamejared/controlling/client/FreeKeysList.java

@@ -0,0 +1,144 @@
+package com.blamejared.controlling.client;
+
+import com.blamejared.controlling.mixin.AccessInputConstantsKey;
+import com.blamejared.controlling.mixin.AccessKeyMapping;
+import com.google.common.collect.ImmutableList;
+import com.mojang.blaze3d.platform.InputConstants;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.client.KeyMapping;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.narration.NarratableEntry;
+import net.minecraft.client.gui.screens.controls.KeyBindsScreen;
+import net.minecraft.network.chat.TranslatableComponent;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+public class FreeKeysList extends CustomList {
+    
+    private final KeyBindsScreen controlsScreen;
+    private final Minecraft mc;
+    private int maxListLabelWidth;
+    
+    List<KeyMapping> keyBindings;
+    
+    public FreeKeysList(KeyBindsScreen controls, Minecraft mcIn) {
+        
+        super(controls, mcIn);
+        this.width = controls.width + 45;
+        this.height = controls.height;
+        this.y0 = 43;
+        this.y1 = controls.height - 80;
+        this.x1 = controls.width + 45;
+        this.controlsScreen = controls;
+        this.mc = mcIn;
+        children().clear();
+        allEntries = new ArrayList<>();
+        keyBindings = Arrays.stream(mc.options.keyMappings).collect(Collectors.toList());
+        
+        recalculate();
+        
+    }
+    
+    public void recalculate() {
+        
+        children().clear();
+        allEntries.clear();
+        
+        addEntry(new HeaderEntry("Available Keys"));
+        AccessInputConstantsKey.getNAME_MAP().values().stream().filter(input -> !input.toString().startsWith("key.keyboard.world")).sorted(Comparator.comparing(o -> o.getDisplayName().getString())).forEach(input -> {
+            if(keyBindings.stream().noneMatch(keyBinding -> ((AccessKeyMapping) keyBinding).getKey().equals(input))) {
+                int i = mc.font.width(input.getDisplayName().getString());
+                if(i > this.maxListLabelWidth) {
+                    this.maxListLabelWidth = i;
+                }
+                addEntry(new InputEntry(input));
+            }
+        });
+    }
+    
+    @Override
+    protected int getScrollbarPosition() {
+        
+        return super.getScrollbarPosition() + 15 + 20;
+    }
+    
+    @Override
+    public int getRowWidth() {
+        
+        return super.getRowWidth() + 32;
+    }
+    
+    public class InputEntry extends Entry {
+        
+        private final InputConstants.Key input;
+        
+        public InputEntry(InputConstants.Key input) {
+            
+            this.input = input;
+        }
+        
+        public InputConstants.Key getInput() {
+            
+            return input;
+        }
+        
+        @Override
+        public void render(PoseStack stack, int slotIndex, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovered, float partialTicks) {
+            
+            String str = this.input.toString() + " - " + input.getValue();
+            int length = mc.font.width(input.getDisplayName().getString());
+            
+            FreeKeysList.this.mc.font.draw(stack, str, x, (float) (y + height / 2 - 9 / 2), 16777215);
+            controlsScreen.renderTooltip(stack, input.getDisplayName(), x + width - (length), y + height);
+        }
+        
+        @Override
+        public List<? extends NarratableEntry> narratables() {
+            
+            return ImmutableList.of();
+        }
+        
+        @Override
+        public List<? extends GuiEventListener> children() {
+            
+            return ImmutableList.of();
+        }
+        
+    }
+    
+    public class HeaderEntry extends Entry {
+        
+        private final String text;
+        
+        public HeaderEntry(String text) {
+            
+            this.text = text;
+        }
+        
+        @Override
+        public List<? extends NarratableEntry> narratables() {
+            
+            return ImmutableList.of();
+        }
+        
+        @Override
+        public List<? extends GuiEventListener> children() {
+            
+            return ImmutableList.of();
+        }
+        
+        @Override
+        public void render(PoseStack stack, int slotIndex, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovered, float partialTicks) {
+            
+            drawCenteredString(stack, mc.font, new TranslatableComponent("options.availableKeys"), (Objects.requireNonNull(mc.screen).width / 2 - this.text.length() / 2), (y + height - 9 - 1), 16777215);
+        }
+        
+    }
+    
+}

+ 294 - 0
Common/src/main/java/com/blamejared/controlling/client/NewKeyBindsList.java

@@ -0,0 +1,294 @@
+package com.blamejared.controlling.client;
+
+import com.blamejared.controlling.api.events.IKeyEntryListenersEvent;
+import com.blamejared.controlling.api.events.IKeyEntryMouseClickedEvent;
+import com.blamejared.controlling.api.events.IKeyEntryMouseReleasedEvent;
+import com.blamejared.controlling.platform.Services;
+import com.google.common.collect.ImmutableList;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.ChatFormatting;
+import net.minecraft.client.KeyMapping;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.components.Button;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.narration.NarratableEntry;
+import net.minecraft.client.gui.narration.NarratedElementType;
+import net.minecraft.client.gui.narration.NarrationElementOutput;
+import net.minecraft.client.gui.screens.controls.KeyBindsList;
+import net.minecraft.client.gui.screens.controls.KeyBindsScreen;
+import net.minecraft.client.resources.language.I18n;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.MutableComponent;
+import net.minecraft.network.chat.TextComponent;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.util.Mth;
+import org.apache.commons.lang3.ArrayUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.UnaryOperator;
+
+public class NewKeyBindsList extends CustomList {
+    
+    private final KeyBindsScreen controlsScreen;
+    private final Minecraft mc;
+    private int maxListLabelWidth;
+    
+    public NewKeyBindsList(KeyBindsScreen controls, Minecraft mcIn) {
+        
+        super(controls, mcIn);
+        this.width = controls.width + 45;
+        this.height = controls.height;
+        this.y0 = 20;
+        this.y1 = controls.height - 80;
+        this.x1 = controls.width + 45;
+        this.controlsScreen = controls;
+        this.mc = mcIn;
+        children().clear();
+        allEntries = new ArrayList<>();
+        KeyMapping[] bindings = ArrayUtils.clone(mcIn.options.keyMappings);
+        Arrays.sort(bindings);
+        String lastCategory = null;
+        
+        for(KeyMapping keybinding : bindings) {
+            String category = keybinding.getCategory();
+            if(!category.equals(lastCategory)) {
+                lastCategory = category;
+                if(!category.endsWith(".hidden")) {
+                    addEntry(new NewKeyBindsList.CategoryEntry(category));
+                }
+            }
+            
+            int width = mcIn.font.width(I18n.get(keybinding.getName()));
+            if(width > this.maxListLabelWidth) {
+                this.maxListLabelWidth = width;
+            }
+            if(!category.endsWith(".hidden")) {
+                addEntry(new NewKeyBindsList.KeyEntry(keybinding));
+            }
+        }
+        
+    }
+    
+    @Override
+    protected void renderDecorations(PoseStack matrixStack, int mouseX, int mouseY) {
+        
+        Entry entry = this.getEntryAtPos(mouseY);
+        if(entry instanceof KeyEntry keyEntry) {
+            
+            controlsScreen.renderTooltip(matrixStack, new TranslatableComponent(keyEntry.getKeybinding().getCategory()), mouseX, mouseY);
+        }
+    }
+    
+    public Entry getEntryAtPos(double mouseY) {
+        
+        if(mouseY <= this.y0 || mouseY >= this.y1) {
+            return null;
+        }
+        int i1 = Mth.floor(mouseY - (double) this.y0) - this.headerHeight + (int) this.getScrollAmount() - 4;
+        int itemIndex = i1 / this.itemHeight;
+        return i1 >= 0 && itemIndex < this.getItemCount() ? this.children().get(itemIndex) : null;
+    }
+    
+    @Override
+    protected int getScrollbarPosition() {
+        
+        return super.getScrollbarPosition() + 15 + 20;
+    }
+    
+    @Override
+    public int getRowWidth() {
+        
+        return super.getRowWidth() + 32;
+    }
+    
+    public class CategoryEntry extends KeyBindsList.Entry {
+        
+        private final String labelText;
+        private final int labelWidth;
+        private final String name;
+        
+        public CategoryEntry(String name) {
+            
+            this.labelText = I18n.get(name);
+            this.labelWidth = NewKeyBindsList.this.mc.font.width(this.labelText);
+            this.name = name;
+        }
+        
+        public String getName() {
+            
+            return name;
+        }
+        
+        public void render(PoseStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
+            
+            NewKeyBindsList.this.minecraft.font.draw(stack, this.labelText, (float) (Objects.requireNonNull(minecraft.screen).width / 2 - this.labelWidth / 2), (float) (y + rowWidth - 9 - 1), 16777215);
+        }
+        
+        public List<? extends NarratableEntry> narratables() {
+            
+            return ImmutableList.of(new NarratableEntry() {
+                public NarrationPriority narrationPriority() {
+                    
+                    return NarrationPriority.HOVERED;
+                }
+                
+                public void updateNarration(NarrationElementOutput neo) {
+                    
+                    neo.add(NarratedElementType.TITLE, labelText);
+                }
+            });
+        }
+        
+        @Override
+        public List<? extends GuiEventListener> children() {
+            
+            return ImmutableList.of();
+        }
+        
+    }
+    
+    public class KeyEntry extends KeyBindsList.Entry {
+        
+        /**
+         * The keybinding specified for this KeyEntry
+         */
+        private final KeyMapping keybinding;
+        /**
+         * The localized key description for this KeyEntry
+         */
+        private final String keyDesc;
+        private final Button btnChangeKeyBinding;
+        private final Button btnResetKeyBinding;
+        
+        
+        private KeyEntry(final KeyMapping name) {
+            
+            this.keybinding = name;
+            this.keyDesc = I18n.get(name.getName());
+            this.btnChangeKeyBinding = new Button(0, 0, 75 + 20, 20, new TextComponent(this.keyDesc), (btn) -> NewKeyBindsList.this.controlsScreen.selectedKey = name) {
+                
+                @Override
+                protected MutableComponent createNarrationMessage() {
+                    
+                    return name.isUnbound() ? new TranslatableComponent("narrator.controls.unbound", NewKeyBindsList.KeyEntry.this.keyDesc) : new TranslatableComponent("narrator.controls.bound", NewKeyBindsList.KeyEntry.this.keyDesc, super.createNarrationMessage());
+                }
+                
+            };
+            this.btnResetKeyBinding = new Button(0, 0, 50, 20, new TranslatableComponent("controls.reset"), (btn) -> {
+                Services.PLATFORM.setToDefault(minecraft.options, name);
+                KeyMapping.resetMapping();
+            }) {
+                
+                @Override
+                protected MutableComponent createNarrationMessage() {
+                    
+                    return new TranslatableComponent("narrator.controls.reset", NewKeyBindsList.KeyEntry.this.keyDesc);
+                }
+            };
+        }
+        
+        @Override
+        public void render(PoseStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
+            Services.EVENT.fireKeyEntryRenderEvent(this, stack, slotIndex, y, x, rowLeft, rowWidth, mouseX, mouseY, hovered, partialTicks);
+            boolean flag = NewKeyBindsList.this.controlsScreen.selectedKey == this.keybinding;
+            int length = Math.max(0, x + 90 - NewKeyBindsList.this.maxListLabelWidth);
+            NewKeyBindsList.this.mc.font.draw(stack, this.keyDesc, (float) (length), (float) (y + rowWidth / 2 - 9 / 2), 16777215);
+            this.btnResetKeyBinding.x = x + 190 + 20;
+            this.btnResetKeyBinding.y = y;
+            this.btnResetKeyBinding.active = !this.keybinding.isDefault();
+            this.btnResetKeyBinding.render(stack, mouseX, mouseY, partialTicks);
+            
+            
+            this.btnChangeKeyBinding.x = x + 105;
+            this.btnChangeKeyBinding.y = y;
+            this.btnChangeKeyBinding.setMessage(this.keybinding.getTranslatedKeyMessage());
+            
+            boolean flag1 = false;
+            boolean keyCodeModifierConflict = true;
+            if(!this.keybinding.isUnbound()) {
+                for(KeyMapping otherBinding : NewKeyBindsList.this.mc.options.keyMappings) {
+                    if(otherBinding != this.keybinding && this.keybinding.same(otherBinding)) {
+                        flag1 = true;
+                        
+                        keyCodeModifierConflict &= Services.PLATFORM.hasConflictingModifier(keybinding, otherBinding);
+                    }
+                }
+            }
+            Component message = this.btnChangeKeyBinding.getMessage();
+            if(flag) {
+                this.btnChangeKeyBinding.setMessage(new TextComponent(ChatFormatting.WHITE + "> " + ChatFormatting.YELLOW + message.getString() + ChatFormatting.WHITE + " <"));
+            } else if(flag1) {
+                this.btnChangeKeyBinding.setMessage(message.copy().withStyle(keyCodeModifierConflict ? ChatFormatting.GOLD : ChatFormatting.RED));
+            }
+            
+            this.btnChangeKeyBinding.render(stack, mouseX, mouseY, partialTicks);
+        }
+        
+        public List<GuiEventListener> children() {
+            
+            return Services.EVENT.fireKeyEntryListenersEvent(this).map(IKeyEntryListenersEvent::getListeners, UnaryOperator.identity());
+        }
+        
+        @Override
+        public Optional<GuiEventListener> getChildAt(double p_94730_, double p_94731_) {
+            
+            return super.getChildAt(p_94730_, p_94731_);
+        }
+        
+        public List<? extends NarratableEntry> narratables() {
+            
+            return ImmutableList.of(this.btnChangeKeyBinding, this.btnResetKeyBinding);
+        }
+        
+        @Override
+        public boolean mouseClicked(double mouseX, double mouseY, int buttonId) {
+            
+            if(Services.EVENT.fireKeyEntryMouseClickedEvent(this, mouseX, mouseY, buttonId).map(IKeyEntryMouseClickedEvent::isHandled, UnaryOperator.identity())) {
+                return true;
+            }
+            
+            if(this.btnChangeKeyBinding.mouseClicked(mouseX, mouseY, buttonId)) {
+                return true;
+            } else {
+                return this.btnResetKeyBinding.mouseClicked(mouseX, mouseY, buttonId);
+            }
+        }
+        
+        
+        @Override
+        public boolean mouseReleased(double mouseX, double mouseY, int buttonId) {
+            
+            if(Services.EVENT.fireKeyEntryMouseReleasedEvent(this, mouseX, mouseY, buttonId).map(IKeyEntryMouseReleasedEvent::isHandled, UnaryOperator.identity())) {
+                return true;
+            }
+            
+            return this.btnChangeKeyBinding.mouseReleased(mouseX, mouseY, buttonId);
+        }
+        
+        public KeyMapping getKeybinding() {
+            
+            return keybinding;
+        }
+        
+        public String getKeyDesc() {
+            
+            return keyDesc;
+        }
+        
+        public Button getBtnResetKeyBinding() {
+            
+            return btnResetKeyBinding;
+        }
+        
+        public Button getBtnChangeKeyBinding() {
+            
+            return btnChangeKeyBinding;
+        }
+        
+    }
+    
+}

+ 396 - 0
Common/src/main/java/com/blamejared/controlling/client/NewKeyBindsScreen.java

@@ -0,0 +1,396 @@
+package com.blamejared.controlling.client;
+
+import com.blamejared.controlling.api.DisplayMode;
+import com.blamejared.controlling.api.SearchType;
+import com.blamejared.controlling.api.SortOrder;
+import com.blamejared.controlling.mixin.AccessKeyBindsScreen;
+import com.blamejared.controlling.mixin.AccessKeyMapping;
+import com.blamejared.controlling.mixin.AccessScreen;
+import com.blamejared.controlling.platform.Services;
+import com.mojang.blaze3d.platform.InputConstants;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.Util;
+import net.minecraft.client.KeyMapping;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.Options;
+import net.minecraft.client.gui.components.Button;
+import net.minecraft.client.gui.components.EditBox;
+import net.minecraft.client.gui.components.Widget;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.client.gui.screens.controls.KeyBindsList;
+import net.minecraft.client.gui.screens.controls.KeyBindsScreen;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.TextComponent;
+import net.minecraft.network.chat.TranslatableComponent;
+import org.lwjgl.glfw.GLFW;
+
+import java.util.LinkedHashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
+
+public class NewKeyBindsScreen extends KeyBindsScreen {
+    
+    private Button buttonReset;
+    private final Options options;
+    
+    private String lastSearch;
+    private EditBox search;
+    
+    private DisplayMode displayMode;
+    private SearchType searchType;
+    private SortOrder sortOrder;
+    
+    private Button buttonNone;
+    private Button buttonConflicting;
+    private FancyCheckbox buttonKey;
+    private FancyCheckbox buttonCat;
+    private boolean confirmingReset = false;
+    private boolean showFree = false;
+    
+    private KeyBindsList customKeyList;
+    private FreeKeysList freeKeyList;
+    
+    public NewKeyBindsScreen(Screen screen, Options settings) {
+        
+        super(screen, settings);
+        this.options = settings;
+    }
+    
+    /**
+     * Adds the buttons (and other controls) to the screen in question. Called when the GUI is displayed and when the
+     * window resizes, the buttonList is cleared beforehand.
+     */
+    protected void init() {
+        this.customKeyList = new NewKeyBindsList(this, this.minecraft);
+        this.freeKeyList = new FreeKeysList(this, this.minecraft);
+        this.setKeyBindsList(this.customKeyList);
+        this.addWidget(getKeyBindsList());
+        this.setFocused(getKeyBindsList());
+        this.addRenderableWidget(new Button(this.width / 2 - 155 + 160, this.height - 29, 150, 20, new TranslatableComponent("gui.done"), (btn) -> Objects.requireNonNull(this.minecraft).setScreen(this.lastScreen)));
+        
+        this.buttonReset = this.addRenderableWidget(new Button(this.width / 2 - 155, this.height - 29, 74, 20, new TranslatableComponent("controls.resetAll"), (btn) -> {
+            
+            if(!confirmingReset) {
+                confirmingReset = true;
+                btn.setMessage(new TranslatableComponent("options.confirmReset"));
+                return;
+            }
+            confirmingReset = false;
+            btn.setMessage(new TranslatableComponent("controls.resetAll"));
+            for(KeyMapping keybinding : Objects.requireNonNull(minecraft).options.keyMappings) {
+                Services.PLATFORM.setToDefault(minecraft.options, keybinding);
+                KeyMapping.resetMapping();
+            }
+            
+            KeyMapping.releaseAll();
+        }));
+        this.buttonNone = this.addRenderableWidget(new Button(this.width / 2 - 155 + 160 + 76, this.height - 29 - 24, 150 / 2, 20, new TranslatableComponent("options.showNone"), (btn) -> {
+            if(displayMode == DisplayMode.NONE) {
+                buttonNone.setMessage(new TranslatableComponent("options.showNone"));
+                displayMode = DisplayMode.ALL;
+            } else {
+                displayMode = DisplayMode.NONE;
+                buttonNone.setMessage(new TranslatableComponent("options.showAll"));
+                buttonConflicting.setMessage(new TranslatableComponent("options.showConflicts"));
+            }
+            filterKeys();
+        }));
+        this.buttonConflicting = this.addRenderableWidget(new Button(this.width / 2 - 155 + 160, this.height - 29 - 24, 150 / 2, 20, new TranslatableComponent("options.showConflicts"), (btn) -> {
+            if(displayMode == DisplayMode.CONFLICTING) {
+                buttonConflicting.setMessage(new TranslatableComponent("options.showConflicts"));
+                displayMode = DisplayMode.ALL;
+            } else {
+                displayMode = DisplayMode.CONFLICTING;
+                buttonConflicting.setMessage(new TranslatableComponent("options.showAll"));
+                buttonNone.setMessage(new TranslatableComponent("options.showNone"));
+            }
+            filterKeys();
+        }));
+        search = new EditBox(font, this.width / 2 - 154, this.height - 29 - 23, 148, 18, TextComponent.EMPTY);
+        addWidget(search);
+        this.buttonKey = this.addRenderableWidget(new FancyCheckbox(this.width / 2 - (155 / 2), this.height - 29 - 37, 11, 11, new TranslatableComponent("options.key"), false, btn -> {
+            buttonCat.selected(false);
+            searchType = btn.selected() ? SearchType.KEY : SearchType.NAME;
+            filterKeys();
+        }));
+        this.buttonCat = this.addRenderableWidget(new FancyCheckbox(this.width / 2 - (155 / 2), this.height - 29 - 50, 11, 11, new TranslatableComponent("options.category"), false, btn -> {
+            buttonKey.selected(false);
+            searchType = btn.selected() ? SearchType.CATEGORY : SearchType.NAME;
+            filterKeys();
+        }));
+        sortOrder = SortOrder.NONE;
+        Button buttonSort = this.addRenderableWidget(new Button(this.width / 2 - 155 + 160 + 76, this.height - 29 - 24 - 24, 150 / 2, 20, new TranslatableComponent("options.sort").append(": " + sortOrder.getName()), (btn) -> {
+            sortOrder = sortOrder.cycle();
+            btn.setMessage(new TranslatableComponent("options.sort").append(": " + sortOrder.getName()));
+            filterKeys();
+        }));
+        
+        this.addRenderableWidget(new Button(this.width / 2 - 155 + 76, this.height - 29, 74, 20, new TranslatableComponent("options.toggleFree"), (btn) -> {
+            this.removeWidget(getKeyBindsList());
+            if(showFree) {
+                buttonSort.active = true;
+                buttonCat.active = true;
+                buttonKey.active = true;
+                buttonNone.active = true;
+                buttonConflicting.active = true;
+                buttonReset.active = true;
+                setKeyBindsList(customKeyList);
+            } else {
+                freeKeyList.recalculate();
+                buttonSort.active = false;
+                buttonCat.active = false;
+                buttonKey.active = false;
+                buttonNone.active = false;
+                buttonConflicting.active = false;
+                buttonReset.active = false;
+                setKeyBindsList(freeKeyList);
+            }
+            this.addWidget(getKeyBindsList());
+            this.setFocused(getKeyBindsList());
+            showFree = !showFree;
+        }));
+        
+        lastSearch = "";
+        displayMode = DisplayMode.ALL;
+        searchType = SearchType.NAME;
+    }
+    
+    @Override
+    public boolean charTyped(char character, int code) {
+        
+        return search.charTyped(character, code);
+    }
+    
+    @Override
+    public void tick() {
+        
+        this.search.tick();
+        if(!lastSearch.equals(search.getValue())) {
+            filterKeys();
+        }
+    }
+    
+    public void filterKeys() {
+        
+        lastSearch = search.getValue();
+        getKeyBindsList().children().clear();
+        if(getKeyBindsList() instanceof NewKeyBindsList) {
+            
+            if(lastSearch.isEmpty() && displayMode == DisplayMode.ALL && sortOrder == SortOrder.NONE) {
+                getKeyBindsList().children().addAll(((CustomList) getKeyBindsList()).getAllEntries());
+                return;
+            }
+            getKeyBindsList().setScrollAmount(0);
+            Predicate<NewKeyBindsList.KeyEntry> filters = switch(searchType) {
+                case NAME -> displayMode.getPredicate().and(keyEntry -> keyEntry.getKeyDesc().toLowerCase().contains(lastSearch.toLowerCase()));
+                case CATEGORY -> displayMode.getPredicate().and(keyEntry -> new TranslatableComponent(keyEntry.getKeybinding().getCategory()).getString().toLowerCase().contains(lastSearch.toLowerCase()));
+                case KEY -> displayMode.getPredicate().and(keyEntry -> keyEntry.getKeybinding().getTranslatedKeyMessage().getString().toLowerCase().contains(lastSearch.toLowerCase()));
+            };
+            
+            
+            for(NewKeyBindsList.Entry entry : ((CustomList) getKeyBindsList()).getAllEntries()) {
+                if(searchType == SearchType.CATEGORY && sortOrder == SortOrder.NONE && displayMode == DisplayMode.ALL) {
+                    if(entry instanceof NewKeyBindsList.KeyEntry keyEntry) {
+                        if(filters.test(keyEntry)) {
+                            getKeyBindsList().children().add(entry);
+                        }
+                    } else {
+                        getKeyBindsList().children().add(entry);
+                    }
+                } else {
+                    if(entry instanceof NewKeyBindsList.KeyEntry keyEntry) {
+                        if(filters.test(keyEntry)) {
+                            getKeyBindsList().children().add(entry);
+                        }
+                    }
+                }
+                
+            }
+            if(searchType == SearchType.CATEGORY && sortOrder == SortOrder.NONE && displayMode == DisplayMode.ALL) {
+                Set<NewKeyBindsList.CategoryEntry> categories = new LinkedHashSet<>();
+                
+                for(KeyBindsList.Entry entry : getKeyBindsList().children()) {
+                    if(entry instanceof NewKeyBindsList.CategoryEntry cEntry) {
+                        categories.add(cEntry);
+                        for(KeyBindsList.Entry child : getKeyBindsList().children()) {
+                            if(child instanceof NewKeyBindsList.KeyEntry childEntry) {
+                                if(childEntry.getKeybinding().getCategory().equals(cEntry.getName())) {
+                                    categories.remove(cEntry);
+                                }
+                            }
+                        }
+                    }
+                }
+                getKeyBindsList().children().removeAll(categories);
+            }
+            sortOrder.sort(getKeyBindsList().children());
+            
+        } else if(getKeyBindsList() instanceof FreeKeysList) {
+            if(lastSearch.isEmpty()) {
+                getKeyBindsList().children().addAll(((CustomList) getKeyBindsList()).getAllEntries());
+                return;
+            }
+            getKeyBindsList().setScrollAmount(0);
+            
+            for(FreeKeysList.Entry entry : ((CustomList) getKeyBindsList()).getAllEntries()) {
+                if(entry instanceof FreeKeysList.InputEntry inputEntry) {
+                    if(inputEntry.getInput().toString().toLowerCase().contains(lastSearch.toLowerCase())) {
+                        getKeyBindsList().children().add(entry);
+                    }
+                } else {
+                    getKeyBindsList().children().add(entry);
+                }
+                
+            }
+        }
+    }
+    
+    /**
+     * Draws the screen and all the components in it.
+     */
+    @Override
+    public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
+        
+        this.renderBackground(stack);
+        getKeyBindsList().render(stack, mouseX, mouseY, partialTicks);
+        drawCenteredString(stack, this.font, this.title.getString(), this.width / 2, 8, 16777215);
+        boolean flag = false;
+        
+        if(!showFree) {
+            for(KeyMapping keybinding : this.options.keyMappings) {
+                if(!keybinding.isDefault()) {
+                    flag = true;
+                    break;
+                }
+            }
+        }
+        search.render(stack, mouseX, mouseY, partialTicks);
+        this.buttonReset.active = flag;
+        if(!flag) {
+            confirmingReset = false;
+            buttonReset.setMessage(new TranslatableComponent("controls.resetAll"));
+        }
+        
+        
+        Component text = new TranslatableComponent("options.search");
+        font.draw(stack, text, this.width / 2f - (155 / 2f) - (font.width(text.getString())) - 5, this.height - 29 - 42, 16777215);
+        
+        for(Widget widget : getScreenAccess().getRenderables()) {
+            widget.render(stack, mouseX, mouseY, partialTicks);
+        }
+    }
+    
+    @Override
+    public boolean mouseClicked(double mx, double my, int mb) {
+        
+        boolean valid;
+        if(this.selectedKey != null) {
+            this.options.setKey(this.selectedKey, InputConstants.Type.MOUSE.getOrCreate(mb));
+            this.selectedKey = null;
+            KeyMapping.resetMapping();
+            valid = true;
+            search.setFocus(false);
+        } else if(mb == 0 && getKeyBindsList().mouseClicked(mx, my, mb)) {
+            this.setDragging(true);
+            this.setFocused(getKeyBindsList());
+            valid = true;
+            search.setFocus(false);
+        } else {
+            valid = search.mouseClicked(mx, my, mb);
+            if(!valid && search.isFocused() && mb == 1) {
+                search.setValue("");
+                valid = true;
+            }
+        }
+        
+        if(!valid) {
+            
+            for(GuiEventListener listeners : this.children()) {
+                if(listeners.mouseClicked(mx, my, mb)) {
+                    this.setFocused(listeners);
+                    if(mb == 0) {
+                        this.setDragging(true);
+                    }
+                    
+                    return true;
+                }
+            }
+            
+        }
+        
+        
+        return valid;
+    }
+    
+    @Override
+    public boolean mouseReleased(double mx, double my, int mb) {
+        
+        if(mb == 0 && getKeyBindsList().mouseReleased(mx, my, mb)) {
+            this.setDragging(false);
+            return true;
+        } else if(search.isFocused()) {
+            return search.mouseReleased(mx, my, mb);
+        } else {
+            this.setDragging(false);
+            return false;
+        }
+    }
+    
+    @Override
+    public boolean keyPressed(int keyCode, int scanCode, int modifier) {
+        
+        if(!search.isFocused() && this.selectedKey == null) {
+            if(hasControlDown()) {
+                if(InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_F)) {
+                    search.setFocus(true);
+                    return true;
+                }
+            }
+        }
+        if(search.keyPressed(keyCode, scanCode, modifier)) {
+            return true;
+        }
+        if(search.isFocused()) {
+            if(keyCode == 256) {
+                search.setFocus(false);
+                return true;
+            }
+        }
+        if(this.selectedKey != null) {
+            if(keyCode == 256) {
+                Services.PLATFORM.setKey(options, this.selectedKey, InputConstants.UNKNOWN);
+            } else {
+                Services.PLATFORM.setKey(options, this.selectedKey, InputConstants.getKey(keyCode, scanCode));
+            }
+            if(!Services.PLATFORM.isKeyCodeModifier(((AccessKeyMapping) this.selectedKey).getKey())) {
+                this.selectedKey = null;
+            }
+            this.lastKeySelection = Util.getMillis();
+            KeyMapping.resetMapping();
+            return true;
+        } else {
+            return super.keyPressed(keyCode, scanCode, modifier);
+        }
+    }
+    
+    
+    private KeyBindsList getKeyBindsList() {
+        return getAccess().getKeyBindsList();
+    }
+    
+    
+    private void setKeyBindsList(KeyBindsList newList) {
+        getAccess().setKeyBindsList(newList);
+    }
+    
+    private AccessScreen getScreenAccess() {
+        return ((AccessScreen) this);
+    }
+    
+    private AccessKeyBindsScreen getAccess() {
+        return ((AccessKeyBindsScreen) this);
+    }
+    
+}

+ 17 - 0
Common/src/main/java/com/blamejared/controlling/mixin/AccessInputConstantsKey.java

@@ -0,0 +1,17 @@
+package com.blamejared.controlling.mixin;
+
+import com.mojang.blaze3d.platform.InputConstants;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.Map;
+
+@Mixin(InputConstants.Key.class)
+public interface AccessInputConstantsKey {
+    
+    @Accessor("NAME_MAP")
+    static Map<String, InputConstants.Key> getNAME_MAP() {
+        throw new AssertionError();
+    }
+    
+}

+ 17 - 0
Common/src/main/java/com/blamejared/controlling/mixin/AccessKeyBindsScreen.java

@@ -0,0 +1,17 @@
+package com.blamejared.controlling.mixin;
+
+import net.minecraft.client.gui.screens.controls.KeyBindsList;
+import net.minecraft.client.gui.screens.controls.KeyBindsScreen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(KeyBindsScreen.class)
+public interface AccessKeyBindsScreen {
+    
+    @Accessor("keyBindsList")
+    KeyBindsList getKeyBindsList();
+    
+    @Accessor("keyBindsList")
+    void setKeyBindsList(KeyBindsList newList);
+    
+}

+ 14 - 0
Common/src/main/java/com/blamejared/controlling/mixin/AccessKeyMapping.java

@@ -0,0 +1,14 @@
+package com.blamejared.controlling.mixin;
+
+import com.mojang.blaze3d.platform.InputConstants;
+import net.minecraft.client.KeyMapping;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(KeyMapping.class)
+public interface AccessKeyMapping {
+    
+    @Accessor("key")
+    InputConstants.Key getKey();
+    
+}

+ 13 - 0
Common/src/main/java/com/blamejared/controlling/mixin/AccessOptionsSubScreen.java

@@ -0,0 +1,13 @@
+package com.blamejared.controlling.mixin;
+
+import net.minecraft.client.gui.screens.OptionsSubScreen;
+import net.minecraft.client.gui.screens.Screen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(OptionsSubScreen.class)
+public interface AccessOptionsSubScreen {
+    
+    @Accessor("lastScreen")
+    Screen getLastScreen();
+}

+ 15 - 0
Common/src/main/java/com/blamejared/controlling/mixin/AccessScreen.java

@@ -0,0 +1,15 @@
+package com.blamejared.controlling.mixin;
+
+import net.minecraft.client.gui.components.Widget;
+import net.minecraft.client.gui.screens.Screen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.List;
+
+@Mixin(Screen.class)
+public interface AccessScreen {
+    
+    @Accessor("renderables")
+    List<Widget> getRenderables();
+}

+ 24 - 0
Common/src/main/java/com/blamejared/controlling/platform/IEventHelper.java

@@ -0,0 +1,24 @@
+package com.blamejared.controlling.platform;
+
+
+import com.blamejared.controlling.api.events.IKeyEntryListenersEvent;
+import com.blamejared.controlling.api.events.IKeyEntryMouseClickedEvent;
+import com.blamejared.controlling.api.events.IKeyEntryMouseReleasedEvent;
+import com.blamejared.controlling.api.events.IKeyEntryRenderEvent;
+import com.blamejared.controlling.client.NewKeyBindsList;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.datafixers.util.Either;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+
+import java.util.List;
+
+public interface IEventHelper {
+    
+    Either<IKeyEntryListenersEvent, List<GuiEventListener>> fireKeyEntryListenersEvent(NewKeyBindsList.KeyEntry entry);
+    
+    Either<IKeyEntryMouseClickedEvent, Boolean> fireKeyEntryMouseClickedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId);
+    
+    Either<IKeyEntryMouseReleasedEvent, Boolean> fireKeyEntryMouseReleasedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId);
+    
+    Either<IKeyEntryRenderEvent, Void> fireKeyEntryRenderEvent(NewKeyBindsList.KeyEntry entry, PoseStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks);
+}

+ 25 - 0
Common/src/main/java/com/blamejared/controlling/platform/IPlatformHelper.java

@@ -0,0 +1,25 @@
+package com.blamejared.controlling.platform;
+
+import com.mojang.blaze3d.platform.InputConstants;
+import net.minecraft.client.KeyMapping;
+import net.minecraft.client.Options;
+
+public interface IPlatformHelper {
+    
+    default boolean hasConflictingModifier(KeyMapping keybinding, KeyMapping other) {
+        return false;
+    }
+    
+    default void setKey(Options options, KeyMapping keybinding, InputConstants.Key key) {
+        options.setKey(keybinding, key);
+    }
+    
+    default void setToDefault(Options options, KeyMapping keybinding) {
+        options.setKey(keybinding, keybinding.getDefaultKey());
+    }
+    
+    default boolean isKeyCodeModifier(InputConstants.Key key) {
+        return false;
+    }
+    
+}

+ 19 - 0
Common/src/main/java/com/blamejared/controlling/platform/Services.java

@@ -0,0 +1,19 @@
+package com.blamejared.controlling.platform;
+
+import com.blamejared.controlling.ControllingCommon;
+
+import java.util.ServiceLoader;
+
+public class Services {
+    
+    public static final IEventHelper EVENT = load(IEventHelper.class);
+    public static final IPlatformHelper PLATFORM = load(IPlatformHelper.class);
+    
+    public static <T> T load(Class<T> clazz) {
+        
+        final T loadedService = ServiceLoader.load(clazz).findFirst().orElseThrow(() -> new NullPointerException("Failed to load service for " + clazz.getName()));
+        ControllingCommon.LOG.debug("Loaded {} for service {}", loadedService, clazz);
+        return loadedService;
+    }
+    
+}

+ 0 - 0
src/main/resources/assets/controlling/lang/de_de.json → Common/src/main/resources/assets/controlling/lang/de_de.json


+ 0 - 0
src/main/resources/assets/controlling/lang/en_ca.json → Common/src/main/resources/assets/controlling/lang/en_ca.json


+ 0 - 0
src/main/resources/assets/controlling/lang/en_pt.json → Common/src/main/resources/assets/controlling/lang/en_pt.json


+ 0 - 0
src/main/resources/assets/controlling/lang/en_ud.json → Common/src/main/resources/assets/controlling/lang/en_ud.json


+ 1 - 1
src/main/resources/assets/controlling/lang/en_us.json → Common/src/main/resources/assets/controlling/lang/en_us.json

@@ -11,5 +11,5 @@
   "options.sortAZ": "A->Z",
   "options.sortZA": "Z->A",
   "options.toggleFree": "Toggle Free",
-  "options.confirmReset": "Click to confirm reset!"
+  "options.confirmReset": "Confirm?"
 }

+ 0 - 0
src/main/resources/assets/controlling/lang/es_es.json → Common/src/main/resources/assets/controlling/lang/es_es.json


+ 0 - 0
src/main/resources/assets/controlling/lang/fr_fr.json → Common/src/main/resources/assets/controlling/lang/fr_fr.json


+ 0 - 0
src/main/resources/assets/controlling/lang/it_it.json → Common/src/main/resources/assets/controlling/lang/it_it.json


+ 0 - 0
src/main/resources/assets/controlling/lang/ja_jp.json → Common/src/main/resources/assets/controlling/lang/ja_jp.json


+ 0 - 0
src/main/resources/assets/controlling/lang/pl_pl.json → Common/src/main/resources/assets/controlling/lang/pl_pl.json


+ 0 - 0
src/main/resources/assets/controlling/lang/pt_br.json → Common/src/main/resources/assets/controlling/lang/pt_br.json


+ 0 - 0
src/main/resources/assets/controlling/lang/ru_ru.json → Common/src/main/resources/assets/controlling/lang/ru_ru.json


+ 0 - 0
src/main/resources/assets/controlling/lang/ta_in.json → Common/src/main/resources/assets/controlling/lang/ta_in.json


+ 0 - 0
src/main/resources/assets/controlling/lang/tr_tr.json → Common/src/main/resources/assets/controlling/lang/tr_tr.json


+ 0 - 0
src/main/resources/assets/controlling/lang/uk_ua.json → Common/src/main/resources/assets/controlling/lang/uk_ua.json


+ 0 - 0
src/main/resources/assets/controlling/lang/zh_cn.json → Common/src/main/resources/assets/controlling/lang/zh_cn.json


+ 3 - 6
src/main/resources/assets/controlling/lang/zh_tw.json → Common/src/main/resources/assets/controlling/lang/zh_tw.json

@@ -3,13 +3,10 @@
   "options.showAll": "顯示全部",
   "options.showConflicts": "顯示衝突",
   "options.showNone": "顯示未綁定",
-  "options.availableKeys": "可使用按鍵",
+  "options.availableKeys": "可用按鍵",
   "options.sort": "排序",
   "options.category": "分類",
   "options.key": "按鍵",
-  "options.sortNone": "無",
-  "options.sortAZ": "A 至 Z",
-  "options.sortZA": "Z 至 A",
-  "options.toggleFree": "確認可用性",
-  "options.confirmReset": "請點擊以重設!"
+  "options.toggleFree": "免切換",
+  "options.confirmReset": "按一下以確定重設!"
 }

+ 6 - 0
Common/src/main/resources/pack.mcmeta

@@ -0,0 +1,6 @@
+{
+    "pack": {
+        "description": "${mod_name}",
+        "pack_format": 6
+    }
+}

+ 135 - 0
Fabric/build.gradle

@@ -0,0 +1,135 @@
+buildscript {
+    repositories {
+        maven {
+            name = "BlameJared"
+            url = 'https://maven.blamejared.com'
+        }
+        maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
+    }
+    dependencies {
+        classpath group: 'com.blamejared', name: 'ModTemplate', version: '2.+', changing: true
+    }
+}
+plugins {
+    id 'fabric-loom' version '0.10-SNAPSHOT'
+    id 'maven-publish'
+    id 'idea'
+    id 'com.matthewprenger.cursegradle' version '1.4.0'
+}
+apply plugin: 'com.blamejared.modtemplate'
+import com.blamejared.modtemplate.Utils
+
+archivesBaseName = "${mod_name}-fabric-${minecraft_version}"
+version = Utils.updatingVersion(mod_version)
+
+dependencies {
+    minecraft "com.mojang:minecraft:${minecraft_version}"
+    mappings loom.officialMojangMappings()
+    modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}"
+    modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
+    implementation project(":Common")
+}
+
+loom {
+    runs {
+        client {
+            client()
+            setConfigName("Fabric Client")
+            ideConfigGenerated(true)
+            runDir("run")
+        }
+        server {
+            server()
+            setConfigName("Fabric Server")
+            ideConfigGenerated(true)
+            runDir("run")
+        }
+    }
+}
+
+modTemplate {
+    mcVersion minecraft_version
+    curseHomepage curse_homepage
+    displayName mod_name
+    modLoader "Fabric"
+    changelog {
+        enabled true
+        firstCommit git_first_commit
+        repo git_repo
+    }
+    versionTracker {
+        enabled true
+        author mod_author
+        projectName mod_name
+    }
+    webhook {
+        enabled true
+        curseId curse_project_id
+        avatarUrl mod_avatar
+    }
+}
+
+
+processResources {
+    from project(":Common").sourceSets.main.resources
+    inputs.property "version", project.version
+
+    filesMatching("fabric.mod.json") {
+        expand "version": project.version
+    }
+}
+
+tasks.withType(JavaCompile) {
+    source(project(":Common").sourceSets.main.allSource)
+}
+
+jar {
+    from("LICENSE") {
+        rename { "${it}_${mod_name}" }
+    }
+}
+
+publishing {
+    publications {
+        mavenJava(MavenPublication) {
+            artifact(remapJar) {
+                builtBy remapJar
+            }
+            artifact(sourcesJar) {
+                builtBy remapSourcesJar
+            }
+        }
+    }
+
+    repositories {
+    }
+}
+
+
+curseforge {
+
+    apiKey = findProperty('curseforge_api_token') ?: 0
+    def versions = [minecraft_version]
+
+    project {
+        id = curse_project_id
+        releaseType = 'release'
+        changelog = file("changelog.md")
+        changelogType = 'markdown'
+        addGameVersion "Fabric"
+
+        versions.each {
+
+            addGameVersion "${it}"
+        }
+
+        mainArtifact(file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar"))
+
+        afterEvaluate {
+            uploadTask.dependsOn(remapJar)
+        }
+    }
+    options {
+        forgeGradleIntegration = false;
+    }
+}

+ 20 - 0
Fabric/src/main/java/com/blamejared/controlling/api/event/ControllingEvents.java

@@ -0,0 +1,20 @@
+package com.blamejared.controlling.api.event;
+
+import net.fabricmc.fabric.api.event.Event;
+import net.fabricmc.fabric.api.event.EventFactory;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ControllingEvents {
+    
+    public static final Event<IEventHandler<KeyEntryListenersEvent, List<GuiEventListener>>> KEY_ENTRY_LISTENERS_EVENT = EventFactory.createArrayBacked(IEventHandler.class, listeners -> event -> Arrays.stream(listeners).flatMap(handler -> handler.handle(event).stream()).toList());
+    public static final Event<IEventHandler<KeyEntryMouseClickedEvent, Boolean>> KEY_ENTRY_MOUSE_CLICKED_EVENT = EventFactory.createArrayBacked(IEventHandler.class, listeners -> event -> Arrays.stream(listeners).anyMatch(handler -> handler.handle(event)));
+    public static final Event<IEventHandler<KeyEntryMouseReleasedEvent, Boolean>> KEY_ENTRY_MOUSE_RELEASED_EVENT = EventFactory.createArrayBacked(IEventHandler.class, listeners -> event -> Arrays.stream(listeners).anyMatch(handler -> handler.handle(event)));
+    public static final Event<IEventHandler<KeyEntryRenderEvent, Void>> KEY_ENTRY_RENDER_EVENT = EventFactory.createArrayBacked(IEventHandler.class, listeners -> event -> {
+        Arrays.stream(listeners).forEach(handler -> handler.handle(event));
+        return null;
+    });
+    
+}

+ 6 - 0
Fabric/src/main/java/com/blamejared/controlling/api/event/IEventHandler.java

@@ -0,0 +1,6 @@
+package com.blamejared.controlling.api.event;
+
+public interface IEventHandler<T, U> {
+    
+    U handle(T event);
+}

+ 40 - 0
Fabric/src/main/java/com/blamejared/controlling/api/event/KeyEntryListenersEvent.java

@@ -0,0 +1,40 @@
+package com.blamejared.controlling.api.event;
+
+import com.blamejared.controlling.api.events.IKeyEntryListenersEvent;
+import com.blamejared.controlling.client.NewKeyBindsList;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * GetKeyEntryListenersEvent is called to get the values for {@link NewKeyBindsList.KeyEntry#children()}.
+ * Allowing for mods to add more listeners.
+ */
+public class KeyEntryListenersEvent implements IKeyEntryListenersEvent {
+    
+    private final NewKeyBindsList.KeyEntry entry;
+    
+    private final List<GuiEventListener> listeners;
+    
+    public KeyEntryListenersEvent(NewKeyBindsList.KeyEntry entry) {
+        
+        this.entry = entry;
+        this.listeners = new ArrayList<>();
+        
+        getListeners().add(entry.getBtnChangeKeyBinding());
+        getListeners().add(entry.getBtnResetKeyBinding());
+    }
+    
+    
+    public List<GuiEventListener> getListeners() {
+        
+        return listeners;
+    }
+    
+    public NewKeyBindsList.KeyEntry getEntry() {
+        
+        return entry;
+    }
+    
+}

+ 59 - 0
Fabric/src/main/java/com/blamejared/controlling/api/event/KeyEntryMouseClickedEvent.java

@@ -0,0 +1,59 @@
+package com.blamejared.controlling.api.event;
+
+import com.blamejared.controlling.api.events.IKeyEntryMouseClickedEvent;
+import com.blamejared.controlling.client.NewKeyBindsList;
+
+
+/**
+ * KeyEntryMouseClickedEvent is called at the start of {@link NewKeyBindsList.KeyEntry#mouseClicked(double, double, int)}.
+ * <p>
+ * If you are consuming this event, call {@link KeyEntryMouseClickedEvent#setHandled(boolean)} with a value of {@code true}.
+ */
+public class KeyEntryMouseClickedEvent implements IKeyEntryMouseClickedEvent {
+    
+    private final NewKeyBindsList.KeyEntry entry;
+    private final double mouseX;
+    private final double mouseY;
+    private final int buttonId;
+    
+    private boolean handled;
+    
+    public KeyEntryMouseClickedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
+        
+        this.entry = entry;
+        this.mouseX = mouseX;
+        this.mouseY = mouseY;
+        this.buttonId = buttonId;
+    }
+    
+    public NewKeyBindsList.KeyEntry getEntry() {
+        
+        return entry;
+    }
+    
+    public double getMouseX() {
+        
+        return mouseX;
+    }
+    
+    public double getMouseY() {
+        
+        return mouseY;
+    }
+    
+    public int getButtonId() {
+        
+        return buttonId;
+    }
+    
+    public boolean isHandled() {
+        
+        return handled;
+    }
+    
+    public void setHandled(boolean handled) {
+        
+        this.handled = handled;
+    }
+    
+}

+ 58 - 0
Fabric/src/main/java/com/blamejared/controlling/api/event/KeyEntryMouseReleasedEvent.java

@@ -0,0 +1,58 @@
+package com.blamejared.controlling.api.event;
+
+import com.blamejared.controlling.api.events.IKeyEntryMouseReleasedEvent;
+import com.blamejared.controlling.client.NewKeyBindsList;
+
+/**
+ * KeyEntryMouseReleasedEvent is called at the start of {@link NewKeyBindsList.KeyEntry#mouseReleased(double, double, int)}.
+ * <p>
+ * If you are consuming this event, call {@link KeyEntryMouseReleasedEvent#setHandled(boolean)} with a value of {@code true}.
+ */
+public class KeyEntryMouseReleasedEvent implements IKeyEntryMouseReleasedEvent {
+    
+    private final NewKeyBindsList.KeyEntry entry;
+    private final double mouseX;
+    private final double mouseY;
+    private final int buttonId;
+    
+    private boolean handled;
+    
+    public KeyEntryMouseReleasedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
+        
+        this.entry = entry;
+        this.mouseX = mouseX;
+        this.mouseY = mouseY;
+        this.buttonId = buttonId;
+    }
+    
+    public NewKeyBindsList.KeyEntry getEntry() {
+        
+        return entry;
+    }
+    
+    public double getMouseX() {
+        
+        return mouseX;
+    }
+    
+    public double getMouseY() {
+        
+        return mouseY;
+    }
+    
+    public int getButtonId() {
+        
+        return buttonId;
+    }
+    
+    public boolean isHandled() {
+        
+        return handled;
+    }
+    
+    public void setHandled(boolean handled) {
+        
+        this.handled = handled;
+    }
+    
+}

+ 96 - 0
Fabric/src/main/java/com/blamejared/controlling/api/event/KeyEntryRenderEvent.java

@@ -0,0 +1,96 @@
+package com.blamejared.controlling.api.event;
+
+import com.blamejared.controlling.api.events.IKeyEntryRenderEvent;
+import com.blamejared.controlling.client.NewKeyBindsList;
+import com.mojang.blaze3d.vertex.PoseStack;
+
+/**
+ * RenderKeyEntryEvent is called at the top of {@link NewKeyBindsList.KeyEntry#render(PoseStack, int, int, int, int, int, int, int, boolean, float)}
+ * is called, allowing mods to render additional info.
+ */
+public class KeyEntryRenderEvent implements IKeyEntryRenderEvent {
+    
+    private final NewKeyBindsList.KeyEntry entry;
+    
+    private final PoseStack stack;
+    private final int slotIndex;
+    private final int y;
+    private final int x;
+    private final int rowLeft;
+    private final int rowWidth;
+    private final int mouseX;
+    private final int mouseY;
+    private final boolean hovered;
+    private final float partialTicks;
+    
+    public KeyEntryRenderEvent(NewKeyBindsList.KeyEntry entry, PoseStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
+        
+        this.entry = entry;
+        this.stack = stack;
+        this.slotIndex = slotIndex;
+        this.y = y;
+        this.x = x;
+        this.rowLeft = rowLeft;
+        this.rowWidth = rowWidth;
+        this.mouseX = mouseX;
+        this.mouseY = mouseY;
+        this.hovered = hovered;
+        this.partialTicks = partialTicks;
+    }
+    
+    public NewKeyBindsList.KeyEntry getEntry() {
+        
+        return entry;
+    }
+    
+    public PoseStack getStack() {
+        
+        return stack;
+    }
+    
+    public int getSlotIndex() {
+        
+        return slotIndex;
+    }
+    
+    public int getY() {
+        
+        return y;
+    }
+    
+    public int getX() {
+        
+        return x;
+    }
+    
+    public int getRowLeft() {
+        
+        return rowLeft;
+    }
+    
+    public int getRowWidth() {
+        
+        return rowWidth;
+    }
+    
+    public int getMouseX() {
+        
+        return mouseX;
+    }
+    
+    public int getMouseY() {
+        
+        return mouseY;
+    }
+    
+    public boolean isHovered() {
+        
+        return hovered;
+    }
+    
+    public float getPartialTicks() {
+        
+        return partialTicks;
+    }
+    
+}

+ 33 - 0
Fabric/src/main/java/com/blamejared/controlling/mixin/OpenGuiMixin.java

@@ -0,0 +1,33 @@
+package com.blamejared.controlling.mixin;
+
+import com.blamejared.controlling.client.NewKeyBindsScreen;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.client.gui.screens.controls.KeyBindsScreen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(Minecraft.class)
+public class OpenGuiMixin {
+    
+    @Shadow
+    public Screen screen;
+    
+    @Inject(method = "setScreen", at = @At("HEAD"))
+    private void dummyGenerateRefmap(Screen screen, CallbackInfo ci) {
+        // NO-OP this injection is only here to generate the refmap
+    }
+    
+    @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true)
+    private Screen upgradeControlScreen(Screen opened) {
+        // Swap the control options screen with our own instance whenever something tries to open one
+        if(opened != null && KeyBindsScreen.class.equals(opened.getClass())) {
+            return new NewKeyBindsScreen(this.screen, Minecraft.getInstance().options);
+        }
+        return opened;
+    }
+}

+ 40 - 0
Fabric/src/main/java/com/blamejared/controlling/platform/FabricEventHandler.java

@@ -0,0 +1,40 @@
+package com.blamejared.controlling.platform;
+
+import com.blamejared.controlling.api.event.ControllingEvents;
+import com.blamejared.controlling.api.event.KeyEntryListenersEvent;
+import com.blamejared.controlling.api.event.KeyEntryMouseClickedEvent;
+import com.blamejared.controlling.api.event.KeyEntryMouseReleasedEvent;
+import com.blamejared.controlling.api.event.KeyEntryRenderEvent;
+import com.blamejared.controlling.api.events.IKeyEntryListenersEvent;
+import com.blamejared.controlling.api.events.IKeyEntryMouseClickedEvent;
+import com.blamejared.controlling.api.events.IKeyEntryMouseReleasedEvent;
+import com.blamejared.controlling.api.events.IKeyEntryRenderEvent;
+import com.blamejared.controlling.client.NewKeyBindsList;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.datafixers.util.Either;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+
+import java.util.List;
+
+public class FabricEventHandler implements IEventHelper {
+    
+    @Override
+    public Either<IKeyEntryListenersEvent, List<GuiEventListener>> fireKeyEntryListenersEvent(NewKeyBindsList.KeyEntry entry) {
+        return Either.right(ControllingEvents.KEY_ENTRY_LISTENERS_EVENT.invoker().handle(new KeyEntryListenersEvent(entry)));
+    }
+    
+    @Override
+    public Either<IKeyEntryMouseClickedEvent, Boolean> fireKeyEntryMouseClickedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
+        return Either.right(ControllingEvents.KEY_ENTRY_MOUSE_CLICKED_EVENT.invoker().handle(new KeyEntryMouseClickedEvent(entry, mouseX, mouseY, buttonId)));
+    }
+    
+    @Override
+    public Either<IKeyEntryMouseReleasedEvent, Boolean> fireKeyEntryMouseReleasedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
+        return Either.right(ControllingEvents.KEY_ENTRY_MOUSE_RELEASED_EVENT.invoker().handle(new KeyEntryMouseReleasedEvent(entry, mouseX, mouseY, buttonId)));
+    }
+    
+    @Override
+    public Either<IKeyEntryRenderEvent, Void> fireKeyEntryRenderEvent(NewKeyBindsList.KeyEntry entry, PoseStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
+        return Either.right(ControllingEvents.KEY_ENTRY_RENDER_EVENT.invoker().handle(new KeyEntryRenderEvent(entry, stack, slotIndex, y, x, rowLeft, rowWidth, mouseX, mouseY, hovered, partialTicks)));
+    }
+}

+ 5 - 0
Fabric/src/main/java/com/blamejared/controlling/platform/FabricPlatformHelper.java

@@ -0,0 +1,5 @@
+package com.blamejared.controlling.platform;
+
+public class FabricPlatformHelper implements IPlatformHelper {
+
+}

+ 1 - 0
Fabric/src/main/resources/META-INF/services/com.blamejared.controlling.platform.IEventHelper

@@ -0,0 +1 @@
+com.blamejared.controlling.platform.FabricEventHandler

+ 1 - 0
Fabric/src/main/resources/META-INF/services/com.blamejared.controlling.platform.IPlatformHelper

@@ -0,0 +1 @@
+com.blamejared.controlling.platform.FabricPlatformHelper

+ 17 - 0
Fabric/src/main/resources/controlling.mixins.json

@@ -0,0 +1,17 @@
+{
+  "required": true,
+  "package": "com.blamejared.controlling.mixin",
+  "compatibilityLevel": "JAVA_17",
+  "mixins": [
+    "AccessInputConstantsKey",
+    "AccessKeyBindsScreen",
+    "AccessKeyMapping",
+    "AccessScreen",
+    "AccessOptionsSubScreen",
+    "OpenGuiMixin"
+  ],
+  "injectors": {
+    "defaultRequire": 1
+  },
+  "refmap": "controlling.refmap.json"
+}

+ 21 - 0
Fabric/src/main/resources/fabric.mod.json

@@ -0,0 +1,21 @@
+{
+  "schemaVersion": 1,
+  "id": "controlling",
+  "name": "Controlling For Fabric",
+  "version": "${version}",
+  "side": "client",
+  "authors": [
+    "Jaredlll08"
+  ],
+  "license": "MIT",
+  "contact": {
+    "homepage": "https://minecraft.curseforge.com/projects/controlling",
+    "sources": "https://github.com/jaredlll08/Controlling"
+  },
+  "description": "Adds the ability to search for keybinds using their name in the KeyBinding menu, this allows players to easily find a key binding in the menu.\n",
+  "entrypoints": {
+  },
+  "mixins": [
+    "controlling.mixins.json"
+  ]
+}

+ 166 - 0
Forge/build.gradle

@@ -0,0 +1,166 @@
+buildscript {
+    repositories {
+        maven { url = 'https://maven.minecraftforge.net' }
+        maven { url = 'https://maven.blamejared.com' }
+        maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
+        mavenCentral()
+    }
+    dependencies {
+        classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
+        classpath 'gradle.plugin.com.matthewprenger:CurseGradle:1.4.0'
+        classpath group: 'com.blamejared', name: 'ModTemplate', version: '2.+', changing: true
+        classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT'
+    }
+}
+apply plugin: 'java'
+apply plugin: 'net.minecraftforge.gradle'
+apply plugin: 'com.blamejared.modtemplate'
+apply plugin: 'eclipse'
+apply plugin: 'org.spongepowered.mixin'
+apply plugin: 'maven-publish'
+apply plugin: 'com.matthewprenger.cursegradle'
+
+import com.blamejared.modtemplate.Utils
+
+archivesBaseName = "${mod_name}-forge-${minecraft_version}"
+version = Utils.updatingVersion(mod_version)
+
+mixin {
+    add sourceSets.main, "controlling.refmap.json"
+}
+
+minecraft {
+    mappings channel: 'official', version: minecraft_version
+
+    if (project.hasProperty('forge_ats_enabled') && project.findProperty('forge_ats_enabled').toBoolean()) {
+        // This location is hardcoded in Forge and can not be changed.
+        // https://github.com/MinecraftForge/MinecraftForge/blob/be1698bb1554f9c8fa2f58e32b9ab70bc4385e60/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java#L123
+        accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
+        project.logger.debug('Forge Access Transformers are enabled for this project.')
+    }
+
+    runs {
+        client {
+            workingDirectory project.file('run')
+            ideaModule "${rootProject.name}.${project.name}.main"
+            taskName 'Client'
+            arg "--mixin=controlling.mixins.json"
+            mods {
+                modClientRun {
+                    source sourceSets.main
+                    source project(":Common").sourceSets.main
+                }
+            }
+        }
+
+        server {
+            workingDirectory project.file('run')
+            ideaModule "${rootProject.name}.${project.name}.main"
+            taskName 'Server'
+            arg "--mixin=controlling.mixins.json"
+            mods {
+                modServerRun {
+                    source sourceSets.main
+                    source project(":Common").sourceSets.main
+                }
+            }
+        }
+
+        data {
+            workingDirectory project.file('run')
+            ideaModule "${rootProject.name}.${project.name}.main"
+            args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
+            taskName 'Data'
+            arg "--mixin=controlling.mixins.json"
+            mods {
+                modDataRun {
+                    source sourceSets.main
+                    source project(":Common").sourceSets.main
+                }
+            }
+        }
+    }
+}
+
+modTemplate {
+    mcVersion minecraft_version
+    curseHomepage curse_homepage
+    displayName mod_name
+    modLoader "Forge"
+    changelog {
+        enabled true
+        firstCommit git_first_commit
+        repo git_repo
+    }
+    versionTracker {
+        enabled true
+        author mod_author
+        projectName mod_name
+    }
+    webhook {
+        enabled true
+        curseId curse_project_id
+        avatarUrl mod_avatar
+    }
+}
+
+
+sourceSets.main.resources.srcDir 'src/generated/resources'
+
+dependencies {
+    minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
+    compileOnly project(":Common")
+    annotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor'
+}
+
+tasks.withType(JavaCompile) {
+    source(project(":Common").sourceSets.main.allSource)
+}
+
+processResources {
+    from project(":Common").sourceSets.main.resources
+}
+
+jar {
+    manifest {
+        attributes([
+                "Specification-Title"     : mod_name,
+                "Specification-Vendor"    : mod_author,
+                "Specification-Version"   : "1",
+                "Implementation-Title"    : project.name,
+                "Implementation-Version"  : project.jar.archiveVersion,
+                "Implementation-Vendor"   : mod_author,
+                "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
+                "MixinConfigs"            : "controlling.mixins.json"
+        ])
+    }
+}
+
+jar.finalizedBy('reobfJar')
+
+publishing {
+    publications {
+        mavenJava(MavenPublication) {
+            artifact jar
+        }
+    }
+    repositories {
+        maven {
+            url "file://${project.projectDir}/mcmodsrepo"
+        }
+    }
+}
+
+
+curseforge {
+
+    apiKey = findProperty('curseforge_api_token') ?: 0
+    project {
+        id = curse_project_id
+        releaseType = 'release'
+        changelog = file("changelog.md")
+        changelogType = 'markdown'
+        addGameVersion "Forge"
+        addGameVersion minecraft_version
+    }
+}

+ 26 - 0
Forge/src/main/java/com/blamejared/controlling/Controlling.java

@@ -0,0 +1,26 @@
+package com.blamejared.controlling;
+
+import com.blamejared.controlling.events.ClientEventHandler;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fml.IExtensionPoint;
+import net.minecraftforge.fml.ModLoadingContext;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
+import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
+import net.minecraftforge.network.NetworkConstants;
+
+@Mod("controlling")
+public class Controlling {
+    
+    public Controlling() {
+        
+        ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (remote, isServer) -> true));
+        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init);
+    }
+    
+    private void init(final FMLClientSetupEvent event) {
+        
+        MinecraftForge.EVENT_BUS.register(new ClientEventHandler());
+    }
+    
+}

+ 40 - 0
Forge/src/main/java/com/blamejared/controlling/api/events/KeyEntryListenersEvent.java

@@ -0,0 +1,40 @@
+package com.blamejared.controlling.api.events;
+
+import com.blamejared.controlling.client.NewKeyBindsList;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraftforge.eventbus.api.Event;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * GetKeyEntryListenersEvent is called to get the values for {@link NewKeyBindsList.KeyEntry#children()}.
+ * Allowing for mods to add more listeners.
+ */
+public class KeyEntryListenersEvent extends Event implements IKeyEntryListenersEvent {
+    
+    private final NewKeyBindsList.KeyEntry entry;
+    
+    private final List<GuiEventListener> listeners;
+    
+    public KeyEntryListenersEvent(NewKeyBindsList.KeyEntry entry) {
+        
+        this.entry = entry;
+        this.listeners = new ArrayList<>();
+        
+        getListeners().add(entry.getBtnChangeKeyBinding());
+        getListeners().add(entry.getBtnResetKeyBinding());
+    }
+    
+    
+    public List<GuiEventListener> getListeners() {
+        
+        return listeners;
+    }
+    
+    public NewKeyBindsList.KeyEntry getEntry() {
+        
+        return entry;
+    }
+    
+}

+ 7 - 10
src/main/java/com/blamejared/controlling/api/events/KeyEntryMouseClickedEvent.java → Forge/src/main/java/com/blamejared/controlling/api/events/KeyEntryMouseClickedEvent.java

@@ -1,27 +1,24 @@
 package com.blamejared.controlling.api.events;
 
-import com.blamejared.controlling.client.gui.GuiNewKeyBindingList;
-import net.minecraft.client.gui.IGuiEventListener;
+import com.blamejared.controlling.client.NewKeyBindsList;
 import net.minecraftforge.eventbus.api.Event;
 
-import java.util.ArrayList;
-import java.util.List;
 
 /**
- * KeyEntryMouseClickedEvent is called at the start of {@link GuiNewKeyBindingList.KeyEntry#mouseClicked(double, double, int)}.
- *
+ * KeyEntryMouseClickedEvent is called at the start of {@link NewKeyBindsList.KeyEntry#mouseClicked(double, double, int)}.
+ * <p>
  * If you are consuming this event, call {@link KeyEntryMouseClickedEvent#setHandled(boolean)} with a value of {@code true}.
  */
-public class KeyEntryMouseClickedEvent extends Event {
+public class KeyEntryMouseClickedEvent extends Event implements IKeyEntryMouseClickedEvent {
     
-    private final GuiNewKeyBindingList.KeyEntry entry;
+    private final NewKeyBindsList.KeyEntry entry;
     private final double mouseX;
     private final double mouseY;
     private final int buttonId;
     
     private boolean handled;
     
-    public KeyEntryMouseClickedEvent(GuiNewKeyBindingList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
+    public KeyEntryMouseClickedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
         
         this.entry = entry;
         this.mouseX = mouseX;
@@ -29,7 +26,7 @@ public class KeyEntryMouseClickedEvent extends Event {
         this.buttonId = buttonId;
     }
     
-    public GuiNewKeyBindingList.KeyEntry getEntry() {
+    public NewKeyBindsList.KeyEntry getEntry() {
         
         return entry;
     }

+ 6 - 6
src/main/java/com/blamejared/controlling/api/events/KeyEntryMouseReleasedEvent.java → Forge/src/main/java/com/blamejared/controlling/api/events/KeyEntryMouseReleasedEvent.java

@@ -1,23 +1,23 @@
 package com.blamejared.controlling.api.events;
 
-import com.blamejared.controlling.client.gui.GuiNewKeyBindingList;
+import com.blamejared.controlling.client.NewKeyBindsList;
 import net.minecraftforge.eventbus.api.Event;
 
 /**
- * KeyEntryMouseReleasedEvent is called at the start of {@link GuiNewKeyBindingList.KeyEntry#mouseReleased(double, double, int)}.
+ * KeyEntryMouseReleasedEvent is called at the start of {@link NewKeyBindsList.KeyEntry#mouseReleased(double, double, int)}.
  *
  * If you are consuming this event, call {@link KeyEntryMouseReleasedEvent#setHandled(boolean)} with a value of {@code true}.
  */
-public class KeyEntryMouseReleasedEvent extends Event {
+public class KeyEntryMouseReleasedEvent extends Event implements IKeyEntryMouseReleasedEvent {
     
-    private final GuiNewKeyBindingList.KeyEntry entry;
+    private final NewKeyBindsList.KeyEntry entry;
     private final double mouseX;
     private final double mouseY;
     private final int buttonId;
     
     private boolean handled;
     
-    public KeyEntryMouseReleasedEvent(GuiNewKeyBindingList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
+    public KeyEntryMouseReleasedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
         
         this.entry = entry;
         this.mouseX = mouseX;
@@ -25,7 +25,7 @@ public class KeyEntryMouseReleasedEvent extends Event {
         this.buttonId = buttonId;
     }
     
-    public GuiNewKeyBindingList.KeyEntry getEntry() {
+    public NewKeyBindsList.KeyEntry getEntry() {
         
         return entry;
     }

+ 9 - 9
src/main/java/com/blamejared/controlling/api/events/KeyEntryRenderEvent.java → Forge/src/main/java/com/blamejared/controlling/api/events/KeyEntryRenderEvent.java

@@ -1,18 +1,18 @@
 package com.blamejared.controlling.api.events;
 
-import com.blamejared.controlling.client.gui.GuiNewKeyBindingList;
-import com.mojang.blaze3d.matrix.MatrixStack;
+import com.blamejared.controlling.client.NewKeyBindsList;
+import com.mojang.blaze3d.vertex.PoseStack;
 import net.minecraftforge.eventbus.api.Event;
 
 /**
- * RenderKeyEntryEvent is called at the top of {@link com.blamejared.controlling.client.gui.GuiNewKeyBindingList.KeyEntry#render(MatrixStack, int, int, int, int, int, int, int, boolean, float)}
+ * RenderKeyEntryEvent is called at the top of {@link NewKeyBindsList.KeyEntry#render(PoseStack, int, int, int, int, int, int, int, boolean, float)}
  * is called, allowing mods to render additional info.
  */
-public class KeyEntryRenderEvent extends Event {
+public class KeyEntryRenderEvent extends Event implements IKeyEntryRenderEvent {
     
-    private final GuiNewKeyBindingList.KeyEntry entry;
+    private final NewKeyBindsList.KeyEntry entry;
     
-    private final MatrixStack stack;
+    private final PoseStack stack;
     private final int slotIndex;
     private final int y;
     private final int x;
@@ -23,7 +23,7 @@ public class KeyEntryRenderEvent extends Event {
     private final boolean hovered;
     private final float partialTicks;
     
-    public KeyEntryRenderEvent(GuiNewKeyBindingList.KeyEntry entry, MatrixStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
+    public KeyEntryRenderEvent(NewKeyBindsList.KeyEntry entry, PoseStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
         
         this.entry = entry;
         this.stack = stack;
@@ -38,12 +38,12 @@ public class KeyEntryRenderEvent extends Event {
         this.partialTicks = partialTicks;
     }
     
-    public GuiNewKeyBindingList.KeyEntry getEntry() {
+    public NewKeyBindsList.KeyEntry getEntry() {
         
         return entry;
     }
     
-    public MatrixStack getStack() {
+    public PoseStack getStack() {
         
         return stack;
     }

+ 24 - 0
Forge/src/main/java/com/blamejared/controlling/events/ClientEventHandler.java

@@ -0,0 +1,24 @@
+package com.blamejared.controlling.events;
+
+import com.blamejared.controlling.client.NewKeyBindsScreen;
+import com.blamejared.controlling.mixin.AccessOptionsSubScreen;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.screens.controls.KeyBindsScreen;
+import net.minecraftforge.client.event.ScreenOpenEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+
+public class ClientEventHandler {
+    
+    @SubscribeEvent
+    public void openGui(ScreenOpenEvent event) {
+        
+        try {
+            if(event.getScreen() instanceof KeyBindsScreen gui && !(event.getScreen() instanceof NewKeyBindsScreen)) {
+                event.setScreen(new NewKeyBindsScreen(((AccessOptionsSubScreen)gui).getLastScreen(), Minecraft.getInstance().options));
+            }
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+    }
+    
+}

+ 48 - 0
Forge/src/main/java/com/blamejared/controlling/platform/ForgeEventHandler.java

@@ -0,0 +1,48 @@
+package com.blamejared.controlling.platform;
+
+import com.blamejared.controlling.api.events.IKeyEntryListenersEvent;
+import com.blamejared.controlling.api.events.IKeyEntryMouseClickedEvent;
+import com.blamejared.controlling.api.events.IKeyEntryMouseReleasedEvent;
+import com.blamejared.controlling.api.events.IKeyEntryRenderEvent;
+import com.blamejared.controlling.api.events.KeyEntryListenersEvent;
+import com.blamejared.controlling.api.events.KeyEntryMouseClickedEvent;
+import com.blamejared.controlling.api.events.KeyEntryMouseReleasedEvent;
+import com.blamejared.controlling.api.events.KeyEntryRenderEvent;
+import com.blamejared.controlling.client.NewKeyBindsList;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.datafixers.util.Either;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraftforge.common.MinecraftForge;
+
+import java.util.List;
+
+public class ForgeEventHandler implements IEventHelper {
+    
+    @Override
+    public Either<IKeyEntryListenersEvent, List<GuiEventListener>> fireKeyEntryListenersEvent(NewKeyBindsList.KeyEntry entry) {
+        KeyEntryListenersEvent event = new KeyEntryListenersEvent(entry);
+        MinecraftForge.EVENT_BUS.post(event);
+        return Either.left(event);
+    }
+    
+    @Override
+    public Either<IKeyEntryMouseClickedEvent, Boolean> fireKeyEntryMouseClickedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
+        KeyEntryMouseClickedEvent event = new KeyEntryMouseClickedEvent(entry, mouseX, mouseY, buttonId);
+        MinecraftForge.EVENT_BUS.post(event);
+        return Either.left(event);
+    }
+    
+    @Override
+    public Either<IKeyEntryMouseReleasedEvent, Boolean> fireKeyEntryMouseReleasedEvent(NewKeyBindsList.KeyEntry entry, double mouseX, double mouseY, int buttonId) {
+        KeyEntryMouseReleasedEvent event = new KeyEntryMouseReleasedEvent(entry, mouseX, mouseY, buttonId);
+        MinecraftForge.EVENT_BUS.post(event);
+        return Either.left(event);
+    }
+    
+    @Override
+    public Either<IKeyEntryRenderEvent, Void> fireKeyEntryRenderEvent(NewKeyBindsList.KeyEntry entry, PoseStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
+        KeyEntryRenderEvent event = new KeyEntryRenderEvent(entry, stack, slotIndex, y, x, rowLeft, rowWidth, mouseX, mouseY, hovered, partialTicks);
+        MinecraftForge.EVENT_BUS.post(event);
+        return Either.left(event);
+    }
+}

+ 30 - 0
Forge/src/main/java/com/blamejared/controlling/platform/ForgePlatformHelper.java

@@ -0,0 +1,30 @@
+package com.blamejared.controlling.platform;
+
+import com.mojang.blaze3d.platform.InputConstants;
+import net.minecraft.client.KeyMapping;
+import net.minecraft.client.Options;
+import net.minecraftforge.client.settings.KeyModifier;
+
+public class ForgePlatformHelper implements IPlatformHelper {
+    
+    @Override
+    public boolean hasConflictingModifier(KeyMapping keybinding, KeyMapping other) {
+        return keybinding.hasKeyModifierConflict(other);
+    }
+    
+    @Override
+    public void setKey(Options options, KeyMapping keybinding, InputConstants.Key key) {
+        keybinding.setKeyModifierAndCode(KeyModifier.getActiveModifier(), key);
+        IPlatformHelper.super.setKey(options, keybinding, key);
+    }
+    
+    @Override
+    public boolean isKeyCodeModifier(InputConstants.Key key) {
+        return KeyModifier.isKeyCodeModifier(key);
+    }
+    
+    @Override
+    public void setToDefault(Options options, KeyMapping keybinding) {
+        keybinding.setToDefault();
+    }
+}

+ 3 - 0
Forge/src/main/resources/META-INF/accesstransformer.cfg

@@ -0,0 +1,3 @@
+public-f net.minecraft.client.gui.screens.controls.ControlsScreen f_97516_ # controlList
+public net.minecraft.client.gui.screens.OptionsSubScreen f_96281_ # lastScreen
+public com.mojang.blaze3d.platform.InputConstants$Key f_84857_ # REGISTRY

+ 8 - 8
src/main/resources/META-INF/mods.toml → Forge/src/main/resources/META-INF/mods.toml

@@ -1,11 +1,11 @@
 modLoader="javafml"
-loaderVersion="[34,)"
+loaderVersion="[38,)"
 issueTrackerURL="https://github.com/jaredlll08/Controlling/issues"
 license="MIT"
 
 [[mods]]
 modId="controlling"
-updateJSONURL="https://updates.blamejared.com/get?n=controlling&gv=1.16.5"
+updateJSONURL="https://updates.blamejared.com/get?n=controlling&gv=1.18"
 version="${file.jarVersion}"
 displayName="Controlling"
 displayURL="https://minecraft.curseforge.com/projects/controlling"
@@ -15,14 +15,14 @@ Adds the ability to search for keybinds using their name in the KeyBinding menu,
 '''
 itemIcon="minecraft:compass"
   [[dependencies.controlling]]
-    modId="forge"
-    mandatory=true
-    versionRange="[34,)"
-    ordering="NONE"
-    side="CLIENT"
+	modId="forge"
+	mandatory=true
+	versionRange="[38,)"
+	ordering="NONE"
+	side="CLIENT"
   [[dependencies.controlling]]
     modId="minecraft"
     mandatory=true
-    versionRange="[1.16.3,)"
+    versionRange="[1.18,)"
     ordering="NONE"
     side="CLIENT"

+ 1 - 0
Forge/src/main/resources/META-INF/services/com.blamejared.controlling.platform.IEventHelper

@@ -0,0 +1 @@
+com.blamejared.controlling.platform.ForgeEventHandler

+ 1 - 0
Forge/src/main/resources/META-INF/services/com.blamejared.controlling.platform.IPlatformHelper

@@ -0,0 +1 @@
+com.blamejared.controlling.platform.ForgePlatformHelper

+ 16 - 0
Forge/src/main/resources/controlling.mixins.json

@@ -0,0 +1,16 @@
+{
+  "required": true,
+  "package": "com.blamejared.controlling.mixin",
+  "compatibilityLevel": "JAVA_17",
+  "mixins": [
+    "AccessInputConstantsKey",
+    "AccessKeyBindsScreen",
+    "AccessKeyMapping",
+    "AccessScreen",
+    "AccessOptionsSubScreen"
+  ],
+  "injectors": {
+    "defaultRequire": 1
+  },
+  "refmap": "controlling.refmap.json"
+}

+ 1 - 1
LICENSE

@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2017 Jared
+Copyright (c) 2021 Jared
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

+ 35 - 162
build.gradle

@@ -1,177 +1,50 @@
-buildscript {
-    repositories {
-        maven { url = 'https://files.minecraftforge.net/maven' }
-        maven { url = 'https://maven.blamejared.com' }
-        mavenCentral()
-    }
-    dependencies {
-        classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
-        classpath group: 'com.blamejared', name: 'ModTemplate', version: '1.+', changing: true
-    }
-}
-plugins {
-    id "com.matthewprenger.cursegradle" version "1.4.0"
-}
-apply plugin: 'net.minecraftforge.gradle'
-apply plugin: 'com.blamejared.modtemplate'
-apply plugin: 'eclipse'
-apply plugin: 'maven-publish'
-
-version = '7.0.0'
-group = 'com.blamejared.controlling'
-archivesBaseName = 'Controlling'
-
-sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
-
-minecraft {
-    mappings channel: 'snapshot', version: '20201028-1.16.3'
-    accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
-
-    runs {
-        client {
-            workingDirectory project.file('run')
-            taskName 'ControllingClient'
-            mods {
-                examplemod {
-                    source sourceSets.main
-                }
-            }
-        }
-        server {
-            workingDirectory project.file('run')
-            taskName 'ControllingServer'
-            mods {
-                examplemod {
-                    source sourceSets.main
-                }
-            }
+subprojects {
+
+    apply plugin: 'java'
+
+    java.toolchain.languageVersion = JavaLanguageVersion.of(17)
+    java.withSourcesJar()
+    java.withJavadocJar()
+
+    jar {
+        manifest {
+            attributes([
+                    'Specification-Title'     : mod_name,
+                    'Specification-Vendor'    : mod_author,
+                    'Specification-Version'   : project.jar.archiveVersion,
+                    'Implementation-Title'    : project.name,
+                    'Implementation-Version'  : project.jar.archiveVersion,
+                    'Implementation-Vendor'   : mod_author,
+                    'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
+                    'Timestampe'              : System.currentTimeMillis(),
+                    'Built-On-Java'           : "${System.getProperty('java.vm.version')} (${System.getProperty('java.vm.vendor')})",
+                    'Build-On-Minecraft'      : minecraft_version
+            ])
         }
     }
-}
-
-modTemplate {
-    mcVersion "1.16.5"
-    curseHomepage "https://www.curseforge.com/minecraft/mc-mods/controlling"
-    displayName "Controlling"
-
-    changelog {
-        enabled true
-        firstCommit "efff217f353e51ce43751caf94b1924818b710e8"
-        repo "https://github.com/jaredlll08/Controlling"
-    }
-    versionTracker {
-        enabled true
-        author "Jared"
-        projectName "controlling"
-    }
-    webhook {
-        enabled true
-        curseId "250398"
-        avatarUrl "https://media.forgecdn.net/avatars/49/603/636079972364045115.png"
-    }
-}
-
-dependencies {
-    minecraft 'net.minecraftforge:forge:1.16.5-36.0.0'
-}
-
-jar {
-    manifest {
-        attributes([
-                "Specification-Title"     : "controlling",
-                "Specification-Vendor"    : "BlameJared",
-                "Specification-Version"   : "1",
-                "Implementation-Title"    : project.name,
-                "Implementation-Version"  : "${version}",
-                "Implementation-Vendor"   : "controlling",
-                "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")],)
-    }
-}
-
-task sourcesJar(type: Jar, dependsOn: classes) {
-    description = 'Creates a JAR containing the source code.'
-    from sourceSets.main.allSource
-    classifier = 'sources'
-}
-
-task javadocJar(type: Jar, dependsOn: javadoc) {
-    description = 'Creates a JAR containing the JavaDocs.'
-    from javadoc.destinationDir
-    classifier = 'javadoc'
-}
 
-task deobfJar(type: Jar) {
-    description = 'Creates a JAR containing the non-obfuscated compiled code.'
-    from sourceSets.main.output
-    classifier = "deobf"
-}
-
-artifacts {
-    archives sourcesJar
-    archives javadocJar
-    archives deobfJar
-}
-
-publish.dependsOn(project.tasks.getByName("assemble"))
-publish.mustRunAfter(project.tasks.getByName("build"))
-
-publishing {
-
-    publications {
-
-        mavenJava(MavenPublication) {
-
-            groupId project.group
-            artifactId project.archivesBaseName
-            version project.version
-            from components.java
-
-            // Allows the maven pom file to be modified.
-            pom.withXml {
-
-                // Go through all the dependencies.
-                asNode().dependencies.dependency.each { dep ->
-
-                    println 'Surpressing artifact ' + dep.artifactId.last().value().last() + ' from maven dependencies.'
-                    assert dep.parent().remove(dep)
-                }
-            }
-
-            artifact sourcesJar {
-
-                classifier 'sources'
-            }
-            artifact javadocJar {
+    repositories {
 
-                classifier 'javadoc'
-            }
-            artifact deobfJar {
+        mavenCentral()
 
-                classifier 'deobf'
-            }
+        maven {
+            name = 'Sponge / Mixin'
+            url = 'https://repo.spongepowered.org/repository/maven-public/'
         }
-    }
-
-    repositories {
 
         maven {
-
-            url "file://" + System.getenv("local_maven")
+            name = 'BlameJared Maven (CrT / Bookshelf)'
+            url = 'https://maven.blamejared.com'
         }
     }
-}
 
-curseforge {
+    dependencies {
+        implementation 'org.jetbrains:annotations:21.0.1'
+    }
 
-    apiKey = findProperty('curseforge_api_token') ?: 0
-    project {
-        id = "250398"
-        releaseType = 'release'
-        changelog = file("changelog.md")
-        changelogType = 'markdown'
+    tasks.withType(JavaCompile).configureEach {
 
-//        addArtifact(sourcesJar)
-//        addArtifact(javadocJar)
-        addArtifact(deobfJar)
+        it.options.encoding = 'UTF-8'
+        it.options.release = 17
     }
 }

+ 29 - 2
gradle.properties

@@ -1,4 +1,31 @@
-# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
-# This is required to provide enough memory for the Minecraft decompilation process.
+# Project
+mod_version=9.0
+group=com.blamejared.controlling
+
+# Common
+minecraft_version=1.18
+common_runs_enabled=true
+common_client_run_name=Common Client
+common_server_run_name=Common Server
+
+# Forge
+forge_version=38.0.8
+//forge_ats_enabled=true
+
+# Fabric
+fabric_version=0.43.1+1.18
+fabric_loader_version=0.12.8
+
+# Mod options
+mod_name=Controlling
+mod_author=Jaredlll08
+mod_id=controlling
+mod_avatar=https://media.forgecdn.net/avatars/49/603/636079972364045115.png
+curse_project_id=250398
+curse_homepage=https://www.curseforge.com/minecraft/mc-mods/controlling
+git_first_commit=f55e1b9e9e9d2e7c1ebe2a7dee913c98d473b5c6
+git_repo=https://github.com/jaredlll08/controlling
+
+# Gradle
 org.gradle.jvmargs=-Xmx3G
 org.gradle.daemon=false

BIN
gradle/wrapper/gradle-wrapper.jar


+ 1 - 1
gradle/wrapper/gradle-wrapper.properties

@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip

+ 41 - 30
gradlew

@@ -1,4 +1,20 @@
-#!/usr/bin/env sh
+#!/usr/bin/env bash
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 
 ##############################################################################
 ##
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
 APP_BASE_NAME=`basename "$0"`
 
 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD="maximum"
@@ -56,7 +72,7 @@ case "`uname`" in
   Darwin* )
     darwin=true
     ;;
-  MINGW* )
+  MSYS* | MINGW* )
     msys=true
     ;;
   NONSTOP* )
@@ -66,6 +82,7 @@ esac
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
+
 # Determine the Java command to use to start the JVM.
 if [ -n "$JAVA_HOME" ] ; then
     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
 fi
 
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
     JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
@@ -138,35 +156,28 @@ if $cygwin ; then
         else
             eval `echo args$i`="\"$arg\""
         fi
-        i=$((i+1))
+        i=`expr $i + 1`
     done
     case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
     esac
 fi
 
-# Escape application args
-save () {
-    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
-    echo " "
-}
-APP_ARGS=$(save "$@")
+ARGV=("$@")
+eval set -- $DEFAULT_JVM_OPTS
 
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
-  cd "$(dirname "$0")"
-fi
+IFS=$'
+' read -rd '' -a JAVA_OPTS_ARR <<< "$(echo $JAVA_OPTS | xargs -n1)"
+IFS=$'
+' read -rd '' -a GRADLE_OPTS_ARR <<< "$(echo $GRADLE_OPTS | xargs -n1)"
 
-exec "$JAVACMD" "$@"
+exec "$JAVACMD" "$@" "${JAVA_OPTS_ARR[@]}" "${GRADLE_OPTS_ARR[@]}" "-Dorg.gradle.appname=$APP_BASE_NAME" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "${ARGV[@]}"

+ 24 - 19
gradlew.bat

@@ -1,3 +1,19 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
 @if "%DEBUG%" == "" @echo off
 @rem ##########################################################################
 @rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
 set APP_BASE_NAME=%~n0
 set APP_HOME=%DIRNAME%
 
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
 
 @rem Find java.exe
 if defined JAVA_HOME goto findJavaFromJavaHome
 
 set JAVA_EXE=java.exe
 %JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
 
 echo.
 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
 set JAVA_HOME=%JAVA_HOME:"=%
 set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
 
 echo.
 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
 
 goto fail
 
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
 :execute
 @rem Setup the command line
 
 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 
+
 @rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
 
 :end
 @rem End local scope for the variables with windows NT shell

+ 17 - 0
settings.gradle

@@ -0,0 +1,17 @@
+pluginManagement {
+    repositories {
+        maven { url = 'https://maven.blamejared.com' }
+        gradlePluginPortal()
+        maven {
+            name = 'Fabric'
+            url = 'https://maven.fabricmc.net/'
+        }
+        maven {
+            name = 'Sponge Snapshots'
+            url = 'https://repo.spongepowered.org/repository/maven-public/'
+        }
+    }
+}
+
+rootProject.name = 'Controlling'
+include("Common", "Fabric", "Forge")

+ 0 - 44
src/main/java/com/blamejared/controlling/Controlling.java

@@ -1,44 +0,0 @@
-package com.blamejared.controlling;
-
-import com.blamejared.controlling.events.ClientEventHandler;
-import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.fml.*;
-import net.minecraftforge.fml.common.Mod;
-import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
-import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
-import net.minecraftforge.fml.network.FMLNetworkConstants;
-import org.apache.commons.lang3.tuple.Pair;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.stream.Collectors;
-
-@Mod("controlling")
-public class Controlling {
-    
-    public static Set<String> PATRON_LIST = new HashSet<>();
-    
-    public Controlling() {
-        ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, () -> Pair.of(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true));
-        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init);
-    }
-    
-    private void init(final FMLClientSetupEvent event) {
-        new Thread(() -> {
-            try {
-                URL url = new URL("https://blamejared.com/patrons.txt");
-                URLConnection urlConnection = url.openConnection();
-                urlConnection.setConnectTimeout(15000);
-                urlConnection.setReadTimeout(15000);
-                urlConnection.setRequestProperty("User-Agent", "Controlling|1.16.3");
-                try(BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()))) {
-                    PATRON_LIST = reader.lines().filter(s -> !s.isEmpty()).collect(Collectors.toSet());
-                }
-            } catch(IOException e) {
-                e.printStackTrace();
-            }
-        }).start();
-        MinecraftForge.EVENT_BUS.register(new ClientEventHandler());
-    }
-}

+ 0 - 45
src/main/java/com/blamejared/controlling/api/events/KeyEntryListenersEvent.java

@@ -1,45 +0,0 @@
-package com.blamejared.controlling.api.events;
-
-import com.blamejared.controlling.client.gui.GuiNewKeyBindingList;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.mojang.blaze3d.matrix.MatrixStack;
-import net.minecraft.client.gui.IGuiEventListener;
-import net.minecraftforge.eventbus.api.Event;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * GetKeyEntryListenersEvent is called to get the values for {@link GuiNewKeyBindingList.KeyEntry#getEventListeners()}.
- * Allowing for mods to add more listeners.
- */
-public class KeyEntryListenersEvent extends Event {
-    
-    private final GuiNewKeyBindingList.KeyEntry entry;
-    
-    private final List<IGuiEventListener> listeners;
-    
-    public KeyEntryListenersEvent(GuiNewKeyBindingList.KeyEntry entry) {
-        
-        this.entry = entry;
-        this.listeners = new ArrayList<>();
-        
-        getListeners().add(entry.getBtnChangeKeyBinding());
-        getListeners().add(entry.getBtnResetKeyBinding());
-    }
-    
-    
-    public List<IGuiEventListener> getListeners() {
-        
-        return listeners;
-    }
-    
-    public GuiNewKeyBindingList.KeyEntry getEntry() {
-        
-        return entry;
-    }
-    
-}

+ 0 - 33
src/main/java/com/blamejared/controlling/client/gui/DisplayMode.java

@@ -1,33 +0,0 @@
-package com.blamejared.controlling.client.gui;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.settings.KeyBinding;
-
-import java.util.function.Predicate;
-
-public enum DisplayMode {
-    ALL(keyEntry -> true), NONE(keyEntry -> keyEntry.getKeybinding().isInvalid()), CONFLICTING(keyEntry -> {
-        
-        for(KeyBinding key : Minecraft.getInstance().gameSettings.keyBindings) {
-            if(key.getKeyDescription().equals(keyEntry.getKeybinding().getKeyDescription()) || key.isInvalid()) {
-                continue;
-            } else {
-                if(key.getKey().getKeyCode() == keyEntry.getKeybinding().getKey().getKeyCode()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    });
-    
-    
-    private Predicate<GuiNewKeyBindingList.KeyEntry> predicate;
-    
-    DisplayMode(Predicate<GuiNewKeyBindingList.KeyEntry> predicate) {
-        this.predicate = predicate;
-    }
-    
-    public Predicate<GuiNewKeyBindingList.KeyEntry> getPredicate() {
-        return predicate;
-    }
-}

+ 0 - 67
src/main/java/com/blamejared/controlling/client/gui/GuiCheckBox.java

@@ -1,67 +0,0 @@
-package com.blamejared.controlling.client.gui;
-
-import com.mojang.blaze3d.matrix.MatrixStack;
-import com.mojang.blaze3d.platform.GlStateManager;
-import com.mojang.blaze3d.systems.RenderSystem;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.widget.button.Button;
-import net.minecraft.util.text.StringTextComponent;
-import net.minecraftforge.fml.client.gui.GuiUtils;
-import org.lwjgl.opengl.*;
-
-/**
- * This class provides a checkbox style control.
- */
-public class GuiCheckBox extends Button {
-    
-    private boolean isChecked;
-    private int boxWidth;
-    
-    public GuiCheckBox(int xPos, int yPos, String displayString, boolean isChecked) {
-        super(xPos, yPos, Minecraft.getInstance().fontRenderer.getStringWidth(displayString) + 2 + 11, 11, new StringTextComponent(displayString), b -> {
-        });
-        this.isChecked = isChecked;
-        this.boxWidth = 11;
-        this.height = 11;
-        this.width = this.boxWidth + 2 + Minecraft.getInstance().fontRenderer.getStringWidth(displayString);
-    }
-    
-    @Override
-    public void renderButton(MatrixStack stack, int mouseX, int mouseY, float partial) {
-        if(this.visible) {
-            Minecraft mc = Minecraft.getInstance();
-            this.isHovered = active && mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
-            if(isHovered()) {
-                GuiUtils.drawContinuousTexturedBox(WIDGETS_LOCATION, this.x, this.y, 0, 86, this.boxWidth, this.height, 200, 20, 2, 3, 2, 2, 500);
-                GuiUtils.drawContinuousTexturedBox(WIDGETS_LOCATION, this.x+1, this.y+1, 2, 48, this.boxWidth-2, this.height-2, 200, 20, 1, 0, 1, 0, 500);
-            } else {
-                GuiUtils.drawContinuousTexturedBox(WIDGETS_LOCATION, this.x, this.y, 0, 46, this.boxWidth, this.height, 200, 20, 2, 3, 2, 2, 500);
-            }
-            int color = 14737632;
-            
-            if(packedFGColor != 0) {
-                color = packedFGColor;
-            }
-            if(!this.active) {
-                color = 10526880;
-            }
-            
-            if(this.isChecked)
-                drawCenteredString(stack, mc.fontRenderer, "x", this.x + this.boxWidth / 2 + 1, this.y + 1, 14737632);
-            mc.fontRenderer.func_238407_a_(stack, getMessage().func_241878_f(), this.x + this.boxWidth + 2, this.y + 2, color);
-        }
-    }
-    
-    @Override
-    public void onPress() {
-        this.isChecked = !this.isChecked;
-    }
-    
-    public boolean isChecked() {
-        return this.isChecked;
-    }
-    
-    public void setIsChecked(boolean isChecked) {
-        this.isChecked = isChecked;
-    }
-}

+ 0 - 28
src/main/java/com/blamejared/controlling/client/gui/GuiCustomList.java

@@ -1,28 +0,0 @@
-package com.blamejared.controlling.client.gui;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.screen.ControlsScreen;
-import net.minecraft.client.gui.widget.list.KeyBindingList;
-
-import java.util.List;
-
-public class GuiCustomList  extends KeyBindingList {
-    
-    public List<Entry> allEntries;
-    
-    public GuiCustomList(ControlsScreen controls, Minecraft mcIn) {
-        
-        super(controls, mcIn);
-    }
-    
-    public List<Entry> getAllEntries() {
-        
-        return allEntries;
-    }
-    
-    public void add(Entry ent) {
-        
-        getEventListeners().add(ent);
-        allEntries.add(ent);
-    }
-}

+ 0 - 140
src/main/java/com/blamejared/controlling/client/gui/GuiFreeKeysList.java

@@ -1,140 +0,0 @@
-package com.blamejared.controlling.client.gui;
-
-import com.google.common.collect.ImmutableList;
-import com.mojang.blaze3d.matrix.MatrixStack;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.IGuiEventListener;
-import net.minecraft.client.gui.screen.ControlsScreen;
-import net.minecraft.client.gui.widget.list.KeyBindingList;
-import net.minecraft.client.settings.KeyBinding;
-import net.minecraft.client.util.InputMappings;
-import net.minecraft.util.text.TranslationTextComponent;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
-import net.minecraftforge.fml.client.gui.GuiUtils;
-import sun.security.jca.GetInstance;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@OnlyIn(Dist.CLIENT)
-public class GuiFreeKeysList extends GuiCustomList {
-    
-    private final ControlsScreen controlsScreen;
-    private final Minecraft mc;
-    private int maxListLabelWidth;
-    
-    List<KeyBinding> keyBindings;
-    
-    public GuiFreeKeysList(ControlsScreen controls, Minecraft mcIn) {
-        
-        super(controls, mcIn);
-        this.width = controls.width + 45;
-        this.height = controls.height;
-        this.y0 = 43;
-        this.y1 = controls.height - 80;
-        this.x1 = controls.width + 45;
-        this.controlsScreen = controls;
-        this.mc = mcIn;
-        getEventListeners().clear();
-        allEntries = new ArrayList<>();
-        keyBindings = Arrays.stream(mc.gameSettings.keyBindings).collect(Collectors.toList());
-        
-        recalculate();
-        
-    }
-    
-    public void recalculate() {
-        
-        getEventListeners().clear();
-        allEntries.clear();
-        
-        add(new HeaderEntry("Available Keys"));
-        InputMappings.Input.REGISTRY.values().stream().filter(input -> {
-            return !input.toString().startsWith("key.keyboard.world");
-        }).sorted(Comparator.comparing(o -> o.func_237520_d_().getString())).forEach(input -> {
-            if(keyBindings.stream().noneMatch(keyBinding -> keyBinding.getKey().equals(input))) {
-                int i = mc.fontRenderer.getStringWidth(input.func_237520_d_().getString());
-                if(i > this.maxListLabelWidth) {
-                    this.maxListLabelWidth = i;
-                }
-                add(new InputEntry(input));
-            }
-        });
-    }
-    
-    @Override
-    protected int getScrollbarPosition() {
-        
-        return super.getScrollbarPosition() + 15 + 20;
-    }
-    
-    @Override
-    public int getRowWidth() {
-        
-        return super.getRowWidth() + 32;
-    }
-    
-    @OnlyIn(Dist.CLIENT)
-    public class InputEntry extends Entry {
-        
-        private final InputMappings.Input input;
-        
-        public InputEntry(InputMappings.Input input) {
-            
-            this.input = input;
-        }
-        
-        @Override
-        public List<? extends IGuiEventListener> getEventListeners() {
-            
-            return ImmutableList.of();
-        }
-    
-        public InputMappings.Input getInput() {
-        
-            return input;
-        }
-    
-        @Override
-        public void render(MatrixStack stack, int slotIndex, int y, int x, int p_render_4_, int p_render_5_, int mouseX, int mouseY, boolean p_render_8_, float p_render_9_) {
-            
-            String str = this.input.toString() + " - " + input.getKeyCode();// + " - " + input.func_237520_d_().getString() + " - " + input.getKeyCode();
-            int length = mc.fontRenderer.getStringWidth(input.func_237520_d_().getString());
-            
-            GuiFreeKeysList.this.mc.fontRenderer.drawString(stack, str, x, (float) (y + p_render_5_ / 2 - 9 / 2), 16777215);
-            GuiUtils.drawHoveringText(stack, Collections.singletonList(input.func_237520_d_()), x + p_render_4_ - (length), y + p_render_5_, mc.currentScreen.width, mc.currentScreen.height, -1, mc.fontRenderer);
-            
-        }
-        
-    }
-    
-    @OnlyIn(Dist.CLIENT)
-    public class HeaderEntry extends Entry {
-        
-        private final String text;
-        
-        public HeaderEntry(String text) {
-            
-            this.text = text;
-        }
-        
-        @Override
-        public List<? extends IGuiEventListener> getEventListeners() {
-            
-            return ImmutableList.of();
-        }
-        
-        @Override
-        public void render(MatrixStack stack, int slotIndex, int y, int x, int p_render_4_, int p_render_5_, int mouseX, int mouseY, boolean p_render_8_, float p_render_9_) {
-            
-            drawString(stack, mc.fontRenderer, new TranslationTextComponent("options.availableKeys"),  (mc.currentScreen.width / 2 - this.text.length() / 2), (y + p_render_5_ - 9 - 1), 16777215);
-        }
-        
-    }
-    
-}

+ 0 - 454
src/main/java/com/blamejared/controlling/client/gui/GuiNewControls.java

@@ -1,454 +0,0 @@
-package com.blamejared.controlling.client.gui;
-
-import com.blamejared.controlling.Controlling;
-import com.mojang.blaze3d.matrix.MatrixStack;
-import net.minecraft.client.*;
-import net.minecraft.client.gui.IGuiEventListener;
-import net.minecraft.client.gui.screen.*;
-import net.minecraft.client.gui.widget.TextFieldWidget;
-import net.minecraft.client.gui.widget.button.Button;
-import net.minecraft.client.gui.widget.list.KeyBindingList;
-import net.minecraft.client.settings.KeyBinding;
-import net.minecraft.client.util.InputMappings;
-import net.minecraft.util.Util;
-import net.minecraft.util.text.*;
-import net.minecraftforge.api.distmarker.*;
-import org.lwjgl.glfw.GLFW;
-
-import java.util.*;
-import java.util.function.Predicate;
-
-@OnlyIn(Dist.CLIENT)
-public class GuiNewControls extends ControlsScreen {
-    
-    private Button buttonReset;
-    private final Screen parentScreen;
-    private final GameSettings options;
-    
-    private String lastSearch;
-    private TextFieldWidget search;
-    
-    private DisplayMode displayMode;
-    private SearchType searchType;
-    private SortOrder sortOrder;
-    
-    private Button buttonNone;
-    private Button buttonConflicting;
-    private GuiCheckBox buttonKey;
-    private GuiCheckBox buttonCat;
-    private Button buttonFree;
-    private Button patreonButton;
-    private boolean confirmingReset = false;
-    private boolean showFree = false;
-    private String name;
-    
-    private KeyBindingList customKeyList;
-    private GuiFreeKeysList freeKeyList;
-    
-    public GuiNewControls(Screen screen, GameSettings settings) {
-        
-        super(screen, settings);
-        this.parentScreen = screen;
-        this.options = settings;
-    }
-    
-    /**
-     * Adds the buttons (and other controls) to the screen in question. Called when the GUI is displayed and when the
-     * window resizes, the buttonList is cleared beforehand.
-     */
-    protected void init() {
-        
-        this.addButton(new Button(this.width / 2 - 155, 18, 150, 20, new TranslationTextComponent("options.mouse_settings"), (p_213126_1_) -> {
-            this.minecraft.displayGuiScreen(new MouseSettingsScreen(this, options));
-        }));
-        this.addButton(AbstractOption.AUTO_JUMP.createWidget(this.minecraft.gameSettings, this.width / 2 - 155 + 160, 18, 150));
-        customKeyList = new GuiNewKeyBindingList(this, this.minecraft);
-        freeKeyList = new GuiFreeKeysList(this, this.minecraft);
-        this.keyBindingList = customKeyList;
-        this.children.add(this.keyBindingList);
-        this.setListener(this.keyBindingList);
-        this.addButton(new Button(this.width / 2 - 155 + 160, this.height - 29, 150, 20, new TranslationTextComponent("gui.done"), (p_213126_1_) -> GuiNewControls.this.minecraft.displayGuiScreen(GuiNewControls.this.parentScreen)));
-        
-        this.buttonReset = this.addButton(new Button(this.width / 2 - 155, this.height - 29, 74, 20, new TranslationTextComponent("controls.resetAll"), (p_213126_1_) -> {
-            
-            if(!confirmingReset) {
-                confirmingReset = true;
-                p_213126_1_.setMessage(new TranslationTextComponent("options.confirmReset"));
-                return;
-            }
-            confirmingReset = false;
-            p_213126_1_.setMessage(new TranslationTextComponent("controls.resetAll"));
-            for(KeyBinding keybinding : GuiNewControls.this.minecraft.gameSettings.keyBindings) {
-                keybinding.setToDefault();
-            }
-            
-            KeyBinding.resetKeyBindingArrayAndHash();
-        }));
-        this.buttonNone = this.addButton(new Button(this.width / 2 - 155 + 160 + 76, this.height - 29 - 24, 150 / 2, 20, new TranslationTextComponent("options.showNone"), (p_213126_1_) -> {
-            if(displayMode == DisplayMode.NONE) {
-                buttonNone.setMessage(new TranslationTextComponent("options.showNone"));
-                displayMode = DisplayMode.ALL;
-            } else {
-                displayMode = DisplayMode.NONE;
-                buttonNone.setMessage(new TranslationTextComponent("options.showAll"));
-                buttonConflicting.setMessage(new TranslationTextComponent("options.showConflicts"));
-            }
-            filterKeys();
-        }));
-        this.buttonConflicting = this.addButton(new Button(this.width / 2 - 155 + 160, this.height - 29 - 24, 150 / 2, 20, new TranslationTextComponent("options.showConflicts"), (p_213126_1_) -> {
-            if(displayMode == DisplayMode.CONFLICTING) {
-                buttonConflicting.setMessage(new TranslationTextComponent("options.showConflicts"));
-                displayMode = DisplayMode.ALL;
-            } else {
-                displayMode = DisplayMode.CONFLICTING;
-                buttonConflicting.setMessage(new TranslationTextComponent("options.showAll"));
-                buttonNone.setMessage(new TranslationTextComponent("options.showNone"));
-            }
-            filterKeys();
-        }));
-        search = new TextFieldWidget(font, this.width / 2 - 154, this.height - 29 - 23, 148, 18, new StringTextComponent(""));
-        this.buttonKey = this.addButton(new GuiCheckBox(this.width / 2 - (155 / 2), this.height - 29 - 37, new TranslationTextComponent("options.key").getString(), false) {
-            @Override
-            public void onPress() {
-                
-                super.onPress();
-                buttonCat.setIsChecked(false);
-                searchType = this.isChecked() ? SearchType.KEY : SearchType.NAME;
-                filterKeys();
-            }
-        });
-        this.buttonCat = this.addButton(new GuiCheckBox(this.width / 2 - (155 / 2), this.height - 29 - 50, new TranslationTextComponent("options.category").getString(), false) {
-            
-            @Override
-            public void onPress() {
-                
-                super.onPress();
-                buttonKey.setIsChecked(false);
-                searchType = this.isChecked() ? SearchType.CATEGORY : SearchType.NAME;
-                filterKeys();
-            }
-        });
-        name = Controlling.PATRON_LIST.stream().skip(Controlling.PATRON_LIST.isEmpty() ? 0 : new Random().nextInt(Controlling.PATRON_LIST.size())).findFirst().orElse("");
-        patreonButton = this.addButton(new Button(this.width / 2 - 155 + 160, this.height - 29 - 24 - 24, 150 / 2, 20, new StringTextComponent("Patreon"), p_onPress_1_ -> this.minecraft.displayGuiScreen(new ConfirmOpenLinkScreen((function) -> {
-            if (function) {
-                Util.getOSType().openURI("https://patreon.com/jaredlll08?s=controllingmod");
-            }
-            this.minecraft.displayGuiScreen(this);
-        }, "https://patreon.com/jaredlll08?s=controllingmod", true))) {
-            private boolean wasHovered;
-            
-            @Override
-            public void render(MatrixStack stack, int mouseX, int mouseY, float partialTicks) {
-                
-                if(this.visible) {
-                    this.isHovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
-                    if(this.wasHovered != this.isHovered()) {
-                        if(this.isHovered()) {
-                            if(this.isFocused()) {
-                                this.nextNarration = Util.milliTime() + 200L;
-                            } else {
-                                this.nextNarration = Util.milliTime() + 750L;
-                            }
-                        } else {
-                            this.nextNarration = Long.MAX_VALUE;
-                        }
-                    }
-                    
-                    if(this.visible) {
-                        this.renderButton(stack, mouseX, mouseY, partialTicks);
-                    }
-                    
-                    this.narrate();
-                    this.wasHovered = this.isHovered();
-                }
-            }
-        });
-        sortOrder = SortOrder.NONE;
-        Button buttonSort = this.addButton(new Button(this.width / 2 - 155 + 160 + 76, this.height - 29 - 24 - 24, 150 / 2, 20, new TranslationTextComponent("options.sort").appendString(": " + sortOrder.getName()), (p_213126_1_) -> {
-            sortOrder = sortOrder.cycle();
-            p_213126_1_.setMessage(new TranslationTextComponent("options.sort").appendString(": " + sortOrder.getName()));
-            filterKeys();
-        }));
-        
-        this.buttonFree = this.addButton(new Button(this.width / 2 - 155 + 76, this.height - 29, 74, 20, new TranslationTextComponent("options.toggleFree"), (p_213126_1_) -> {
-            this.children.remove(this.keyBindingList);
-            if(showFree) {
-                buttonSort.active = true;
-                buttonCat.active = true;
-                buttonKey.active = true;
-                buttonNone.active = true;
-                buttonConflicting.active = true;
-                buttonReset.active = true;
-                keyBindingList = customKeyList;
-            } else {
-                freeKeyList.recalculate();
-                buttonSort.active = false;
-                buttonCat.active = false;
-                buttonKey.active = false;
-                buttonNone.active = false;
-                buttonConflicting.active = false;
-                buttonReset.active = false;
-                keyBindingList = freeKeyList;
-            }
-            this.children.add(this.keyBindingList);
-            this.setListener(this.keyBindingList);
-            showFree = !showFree;
-        }));
-        
-        lastSearch = "";
-        displayMode = DisplayMode.ALL;
-        searchType = SearchType.NAME;
-        //        InputMappings.Input.REGISTRY.values().stream().forEach(input -> {
-        //            System.out.println(input.func_237520_d_().getString() + " : " + input.getKeyCode());
-        //        });
-    }
-    
-    @Override
-    public boolean charTyped(char var1, int var2) {
-        
-        return search.charTyped(var1, var2);
-    }
-    
-    @Override
-    public void tick() {
-        
-        this.search.tick();
-        if(!lastSearch.equals(search.getText())) {
-            filterKeys();
-        }
-    }
-    
-    public void filterKeys() {
-        
-        lastSearch = search.getText();
-        keyBindingList.getEventListeners().clear();
-        if(keyBindingList instanceof GuiNewKeyBindingList) {
-            
-            if(lastSearch.isEmpty() && displayMode == DisplayMode.ALL && sortOrder == SortOrder.NONE) {
-                keyBindingList.getEventListeners().addAll(((GuiCustomList) keyBindingList).getAllEntries());
-                return;
-            }
-            this.keyBindingList.setScrollAmount(0);
-            Predicate<GuiNewKeyBindingList.KeyEntry> filters = displayMode.getPredicate();
-            
-            
-            switch(searchType) {
-                case NAME:
-                    filters = filters.and(keyEntry -> keyEntry.getKeyDesc().toLowerCase().contains(lastSearch.toLowerCase()));
-                    break;
-                case CATEGORY:
-                    filters = filters.and(keyEntry -> new TranslationTextComponent(keyEntry.getKeybinding().getKeyCategory()).getString().toLowerCase().contains(lastSearch.toLowerCase()));
-                    break;
-                case KEY:
-                    filters = filters.and(keyEntry -> keyEntry.getKeybinding().func_238171_j_().getString().toLowerCase().contains(lastSearch.toLowerCase()));
-                    break;
-            }
-            
-            for(GuiNewKeyBindingList.Entry entry : ((GuiCustomList) keyBindingList).getAllEntries()) {
-                if(searchType == SearchType.CATEGORY && sortOrder == SortOrder.NONE && displayMode == DisplayMode.ALL) {
-                    if(entry instanceof GuiNewKeyBindingList.KeyEntry) {
-                        GuiNewKeyBindingList.KeyEntry keyEntry = (GuiNewKeyBindingList.KeyEntry) entry;
-                        if(filters.test(keyEntry)) {
-                            keyBindingList.getEventListeners().add(entry);
-                        }
-                    } else {
-                        keyBindingList.getEventListeners().add(entry);
-                    }
-                } else {
-                    if(entry instanceof GuiNewKeyBindingList.KeyEntry) {
-                        GuiNewKeyBindingList.KeyEntry keyEntry = (GuiNewKeyBindingList.KeyEntry) entry;
-                        if(filters.test(keyEntry)) {
-                            keyBindingList.getEventListeners().add(entry);
-                        }
-                    }
-                }
-                
-            }
-            if(searchType == SearchType.CATEGORY && sortOrder == SortOrder.NONE && displayMode == DisplayMode.ALL) {
-                Set<GuiNewKeyBindingList.CategoryEntry> categories = new LinkedHashSet<>();
-                
-                for(KeyBindingList.Entry entry : keyBindingList.getEventListeners()) {
-                    if(entry instanceof GuiNewKeyBindingList.CategoryEntry) {
-                        GuiNewKeyBindingList.CategoryEntry centry = (GuiNewKeyBindingList.CategoryEntry) entry;
-                        categories.add(centry);
-                        for(KeyBindingList.Entry child : keyBindingList.getEventListeners()) {
-                            if(child instanceof GuiNewKeyBindingList.KeyEntry) {
-                                GuiNewKeyBindingList.KeyEntry childEntry = (GuiNewKeyBindingList.KeyEntry) child;
-                                if(childEntry.getKeybinding().getKeyCategory().equals(centry.getName())) {
-                                    categories.remove(centry);
-                                }
-                            }
-                        }
-                    }
-                }
-                keyBindingList.getEventListeners().removeAll(categories);
-            }
-            sortOrder.sort(keyBindingList.getEventListeners());
-            
-        } else if(keyBindingList instanceof GuiFreeKeysList) {
-            if(lastSearch.isEmpty()) {
-                keyBindingList.getEventListeners().addAll(((GuiCustomList) keyBindingList).getAllEntries());
-                return;
-            }
-            this.keyBindingList.setScrollAmount(0);
-            
-            for(GuiFreeKeysList.Entry entry : ((GuiCustomList) keyBindingList).getAllEntries()) {
-                if(entry instanceof GuiFreeKeysList.InputEntry) {
-                    GuiFreeKeysList.InputEntry inputEntry = (GuiFreeKeysList.InputEntry) entry;
-                    if(inputEntry.getInput().toString().toLowerCase().contains(lastSearch.toLowerCase())) {
-                        keyBindingList.getEventListeners().add(entry);
-                    }
-                } else {
-                    keyBindingList.getEventListeners().add(entry);
-                }
-                
-            }
-        }
-    }
-    
-    /**
-     * Draws the screen and all the components in it.
-     */
-    @Override
-    public void render(MatrixStack stack, int mouseX, int mouseY, float partialTicks) {
-        
-        this.renderBackground(stack);
-        this.keyBindingList.render(stack, mouseX, mouseY, partialTicks);
-        drawCenteredString(stack, this.font, this.title.getString(), this.width / 2, 8, 16777215);
-        boolean flag = false;
-        
-        if(!showFree) {
-            for(KeyBinding keybinding : this.options.keyBindings) {
-                if(!keybinding.isDefault()) {
-                    flag = true;
-                    break;
-                }
-            }
-        }
-        search.render(stack, mouseX, mouseY, partialTicks);
-        this.buttonReset.active = flag;
-        if(!flag) {
-            confirmingReset = false;
-            buttonReset.setMessage(new TranslationTextComponent("controls.resetAll"));
-        }
-        for(int i = 0; i < this.buttons.size(); ++i) {
-            this.buttons.get(i).render(stack, mouseX, mouseY, partialTicks);
-        }
-        
-        ITextComponent text = new TranslationTextComponent("options.search");
-        font.func_238407_a_(stack, text.func_241878_f(), this.width / 2f - (155 / 2f) - (font.getStringWidth(text.getString())) - 5, this.height - 29 - 42, 16777215);
-        
-        if(patreonButton.isHovered()) {
-            String str = "Join " + name + " and other patrons!";
-            int tempX = mouseX;
-            int tempY = mouseY;
-            boolean outOfBounds = tempX < patreonButton.x || tempX > patreonButton.x + patreonButton.getWidth();
-            outOfBounds |= tempY < patreonButton.y || tempY > patreonButton.y + patreonButton.getHeightRealms();
-            
-            if(outOfBounds) {
-                tempX = patreonButton.x + patreonButton.getWidth();
-                tempY = patreonButton.y + (patreonButton.getHeightRealms() / 2) + 7;
-            }
-            renderTooltip(stack, new StringTextComponent(str), tempX, tempY);
-        }
-    }
-    
-    @Override
-    public boolean mouseClicked(double mx, double my, int mb) {
-        
-        boolean valid;
-        if(this.buttonId != null) {
-            this.options.setKeyBindingCode(this.buttonId, InputMappings.Type.MOUSE.getOrMakeInput(mb));
-            this.buttonId = null;
-            KeyBinding.resetKeyBindingArrayAndHash();
-            valid = true;
-            search.setFocused2(false);
-        } else if(mb == 0 && this.keyBindingList.mouseClicked(mx, my, mb)) {
-            this.setDragging(true);
-            this.setListener(this.keyBindingList);
-            valid = true;
-            search.setFocused2(false);
-        } else {
-            valid = search.mouseClicked(mx, my, mb);
-            if(!valid && search.isFocused() && mb == 1) {
-                search.setText("");
-                valid = true;
-            }
-        }
-        
-        if(!valid) {
-            
-            for(IGuiEventListener iguieventlistener : this.getEventListeners()) {
-                if(iguieventlistener.mouseClicked(mx, my, mb)) {
-                    this.setListener(iguieventlistener);
-                    if(mb == 0) {
-                        this.setDragging(true);
-                    }
-                    
-                    return true;
-                }
-            }
-            
-            valid = true;
-        }
-        
-        
-        return valid;
-    }
-    
-    @Override
-    public boolean mouseReleased(double mx, double my, int mb) {
-        
-        if(mb == 0 && this.keyBindingList.mouseReleased(mx, my, mb)) {
-            this.setDragging(false);
-            return true;
-        } else if(search.isFocused()) {
-            return search.mouseReleased(mx, my, mb);
-        } else {
-            this.setDragging(false);
-            return false;
-        }
-    }
-    
-    @Override
-    public boolean keyPressed(int keyCode, int scanCode, int modifier) {
-        
-        if(!search.isFocused() && this.buttonId == null) {
-            if(hasControlDown()) {
-                if(InputMappings.isKeyDown(Minecraft.getInstance().getMainWindow().getHandle(), GLFW.GLFW_KEY_F)) {
-                    search.setFocused2(true);
-                    return true;
-                }
-            }
-        }
-        if(search.keyPressed(keyCode, scanCode, modifier)) {
-            return true;
-        }
-        if(search.isFocused()) {
-            if(keyCode == 256) {
-                search.setFocused2(false);
-                return true;
-            }
-        }
-        if(this.buttonId != null) {
-            if(keyCode == 256) {
-                this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), InputMappings.INPUT_INVALID);
-                this.options.setKeyBindingCode(this.buttonId, InputMappings.INPUT_INVALID);
-            } else {
-                this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), InputMappings.getInputByCode(keyCode, scanCode));
-                this.options.setKeyBindingCode(this.buttonId, InputMappings.getInputByCode(keyCode, scanCode));
-            }
-            
-            if(!net.minecraftforge.client.settings.KeyModifier.isKeyCodeModifier(this.buttonId.getKey())) {
-                this.buttonId = null;
-            }
-            this.time = Util.milliTime();
-            KeyBinding.resetKeyBindingArrayAndHash();
-            return true;
-        } else {
-            return super.keyPressed(keyCode, scanCode, modifier);
-        }
-    }
-    
-    
-}

+ 0 - 284
src/main/java/com/blamejared/controlling/client/gui/GuiNewKeyBindingList.java

@@ -1,284 +0,0 @@
-package com.blamejared.controlling.client.gui;
-
-import com.blamejared.controlling.api.events.KeyEntryListenersEvent;
-import com.blamejared.controlling.api.events.KeyEntryMouseClickedEvent;
-import com.blamejared.controlling.api.events.KeyEntryMouseReleasedEvent;
-import com.blamejared.controlling.api.events.KeyEntryRenderEvent;
-import com.google.common.collect.ImmutableList;
-import com.mojang.blaze3d.matrix.MatrixStack;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.IGuiEventListener;
-import net.minecraft.client.gui.screen.ControlsScreen;
-import net.minecraft.client.gui.widget.button.Button;
-import net.minecraft.client.gui.widget.list.KeyBindingList;
-import net.minecraft.client.resources.I18n;
-import net.minecraft.client.settings.KeyBinding;
-import net.minecraft.util.math.MathHelper;
-import net.minecraft.util.text.*;
-import net.minecraftforge.api.distmarker.*;
-import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.fml.client.gui.GuiUtils;
-import org.apache.commons.lang3.ArrayUtils;
-
-import java.util.*;
-
-@OnlyIn(Dist.CLIENT)
-public class GuiNewKeyBindingList extends GuiCustomList {
-    
-    private final ControlsScreen controlsScreen;
-    private final Minecraft mc;
-    private int maxListLabelWidth;
-    
-    public GuiNewKeyBindingList(ControlsScreen controls, Minecraft mcIn) {
-        
-        super(controls, mcIn);
-        this.width = controls.width + 45;
-        this.height = controls.height;
-        this.y0 = 43;
-        this.y1 = controls.height - 80;
-        this.x1 = controls.width + 45;
-        this.controlsScreen = controls;
-        this.mc = mcIn;
-        getEventListeners().clear();
-        allEntries = new ArrayList<>();
-        KeyBinding[] akeybinding = ArrayUtils.clone(mcIn.gameSettings.keyBindings);
-        Arrays.sort(akeybinding);
-        String s = null;
-        
-        for(KeyBinding keybinding : akeybinding) {
-            String s1 = keybinding.getKeyCategory();
-            if(!s1.equals(s)) {
-                s = s1;
-                if(!s1.endsWith(".hidden")) {
-                    add(new GuiNewKeyBindingList.CategoryEntry(s1));
-                }
-            }
-            
-            int i = mcIn.fontRenderer.getStringWidth(I18n.format(keybinding.getKeyDescription()));
-            if(i > this.maxListLabelWidth) {
-                this.maxListLabelWidth = i;
-            }
-            if(!s1.endsWith(".hidden")) {
-                add(new GuiNewKeyBindingList.KeyEntry(keybinding));
-            }
-        }
-        
-    }
-    
-    @Override
-    protected void renderDecorations(MatrixStack matrixStack, int mouseX, int mouseY) {
-        
-        Entry entry = this.getEntryAtPos(mouseY);
-        if(!(entry instanceof KeyEntry)) {
-            return;
-        }
-        KeyEntry keyEntry = (KeyEntry) entry;
-        GuiUtils.drawHoveringText(matrixStack, Collections.singletonList(new TranslationTextComponent(keyEntry
-                .getKeybinding()
-                .getKeyCategory())), mouseX, mouseY, mc.currentScreen.width, mc.currentScreen.height, 0, mc.fontRenderer);
-    }
-    
-    public Entry getEntryAtPos(double mouseY) {
-        
-        if(mouseY <= getTop() || mouseY >= getBottom()) {
-            return null;
-        }
-        int i1 = MathHelper.floor(mouseY - (double) this.y0) - this.headerHeight + (int) this
-                .getScrollAmount() - 4;
-        int j1 = i1 / this.itemHeight;
-        return i1 >= 0 && j1 < this.getItemCount() ? this.getEventListeners()
-                .get(j1) : null;
-    }
-    
-    @Override
-    protected int getScrollbarPosition() {
-        
-        return super.getScrollbarPosition() + 15 + 20;
-    }
-    
-    @Override
-    public int getRowWidth() {
-        
-        return super.getRowWidth() + 32;
-    }
-    
-    @OnlyIn(Dist.CLIENT)
-    public class CategoryEntry extends KeyBindingList.Entry {
-        
-        private final String labelText;
-        private final int labelWidth;
-        private final String name;
-        
-        public CategoryEntry(String name) {
-            
-            this.labelText = I18n.format(name);
-            this.labelWidth = GuiNewKeyBindingList.this.mc.fontRenderer.getStringWidth(this.labelText);
-            this.name = name;
-        }
-        
-        public String getName() {
-            
-            return name;
-        }
-        
-        @Override
-        public List<? extends IGuiEventListener> getEventListeners() {
-            
-            return ImmutableList.of();
-        }
-        
-        public void render(MatrixStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
-            
-            GuiNewKeyBindingList.this.minecraft.fontRenderer.drawString(stack, this.labelText, (float) (GuiNewKeyBindingList.this.minecraft.currentScreen.width / 2 - this.labelWidth / 2), (float) (y + rowWidth - 9 - 1), 16777215);
-        }
-        
-    }
-    
-    @OnlyIn(Dist.CLIENT)
-    public class KeyEntry extends KeyBindingList.Entry {
-        
-        /**
-         * The keybinding specified for this KeyEntry
-         */
-        private final KeyBinding keybinding;
-        /**
-         * The localized key description for this KeyEntry
-         */
-        private final String keyDesc;
-        private final Button btnChangeKeyBinding;
-        private final Button btnResetKeyBinding;
-        
-        
-        private KeyEntry(final KeyBinding name) {
-            
-            this.keybinding = name;
-            this.keyDesc = I18n.format(name.getKeyDescription());
-            this.btnChangeKeyBinding = new Button(0, 0, 75 + 20 /*Forge: add space*/, 20, new StringTextComponent(this.keyDesc), (p_214386_2_) -> {
-                GuiNewKeyBindingList.this.controlsScreen.buttonId = name;
-            }) {
-                @Override
-                protected IFormattableTextComponent getNarrationMessage() {
-                    
-                    return name.isInvalid() ? new TranslationTextComponent("narrator.controls.unbound", GuiNewKeyBindingList.KeyEntry.this.keyDesc) : new TranslationTextComponent("narrator.controls.bound", GuiNewKeyBindingList.KeyEntry.this.keyDesc, super
-                            .getNarrationMessage());
-                }
-            };
-            this.btnResetKeyBinding = new Button(0, 0, 50, 20, new TranslationTextComponent("controls.reset"), (p_214387_2_) -> {
-                keybinding.setToDefault();
-                GuiNewKeyBindingList.this.minecraft.gameSettings.setKeyBindingCode(name, name
-                        .getDefault());
-                KeyBinding.resetKeyBindingArrayAndHash();
-            }) {
-                @Override
-                protected IFormattableTextComponent getNarrationMessage() {
-                    
-                    return new TranslationTextComponent("narrator.controls.reset", GuiNewKeyBindingList.KeyEntry.this.keyDesc);
-                }
-            };
-        }
-        
-        @Override
-        public void render(MatrixStack stack, int slotIndex, int y, int x, int rowLeft, int rowWidth, int mouseX, int mouseY, boolean hovered, float partialTicks) {
-            
-            MinecraftForge.EVENT_BUS.post(new KeyEntryRenderEvent(this, stack, slotIndex, y, x, rowLeft, rowWidth, mouseX, mouseY, hovered, partialTicks));
-            int i = y;
-            int j = x;
-            boolean flag = GuiNewKeyBindingList.this.controlsScreen.buttonId == this.keybinding;
-            int length = Math.max(0, j + 90 - GuiNewKeyBindingList.this.maxListLabelWidth);
-            GuiNewKeyBindingList.this.mc.fontRenderer.drawString(stack, this.keyDesc, (float) (length), (float) (y + rowWidth / 2 - 9 / 2), 16777215);
-            this.btnResetKeyBinding.x = x + 190 + 20;
-            this.btnResetKeyBinding.y = y;
-            this.btnResetKeyBinding.active = !this.keybinding.isDefault();
-            this.btnResetKeyBinding.render(stack, mouseX, mouseY, partialTicks);
-            
-            
-            this.btnChangeKeyBinding.x = j + 105;
-            this.btnChangeKeyBinding.y = i;
-            this.btnChangeKeyBinding.setMessage(this.keybinding.func_238171_j_());
-            
-            boolean flag1 = false;
-            boolean keyCodeModifierConflict = true; // less severe form of conflict, like SHIFT conflicting with SHIFT+G
-            if(!this.keybinding.isInvalid()) {
-                for(KeyBinding keybinding : GuiNewKeyBindingList.this.mc.gameSettings.keyBindings) {
-                    if(keybinding != this.keybinding && this.keybinding.conflicts(keybinding)) {
-                        flag1 = true;
-                        keyCodeModifierConflict &= keybinding.hasKeyCodeModifierConflict(this.keybinding);
-                    }
-                }
-            }
-            ITextComponent message = this.btnChangeKeyBinding.getMessage();
-            if(flag) {
-                this.btnChangeKeyBinding.setMessage(new StringTextComponent(TextFormatting.WHITE + "> " + TextFormatting.YELLOW + message
-                        .getString() + TextFormatting.WHITE + " <"));
-            } else if(flag1) {
-                IFormattableTextComponent modConflict = TextComponentUtils.func_240648_a_(message
-                        .copyRaw(), message.getStyle()
-                        .setColor(Color.fromInt(16755200)));
-                IFormattableTextComponent keyConflict = TextComponentUtils.func_240648_a_(message
-                        .copyRaw(), message.getStyle()
-                        .setColor(Color.fromInt(16755200)));
-                
-                this.btnChangeKeyBinding.setMessage(keyCodeModifierConflict ? modConflict : keyConflict);
-            }
-            
-            this.btnChangeKeyBinding.render(stack, mouseX, mouseY, partialTicks);
-        }
-        
-        public List<IGuiEventListener> getEventListeners() {
-            
-            KeyEntryListenersEvent event = new KeyEntryListenersEvent(this);
-            MinecraftForge.EVENT_BUS.post(event);
-            return event.getListeners();
-        }
-        
-        @Override
-        public boolean mouseClicked(double mouseX, double mouseY, int buttonId) {
-            
-            KeyEntryMouseClickedEvent event = new KeyEntryMouseClickedEvent(this, mouseX, mouseY, buttonId);
-            MinecraftForge.EVENT_BUS.post(event);
-            if(event.isHandled()) {
-                return true;
-            }
-            
-            if(this.btnChangeKeyBinding.mouseClicked(mouseX, mouseY, buttonId)) {
-                return true;
-            } else {
-                return this.btnResetKeyBinding.mouseClicked(mouseX, mouseY, buttonId);
-            }
-        }
-        
-        @Override
-        public boolean mouseReleased(double mouseX, double mouseY, int buttonId) {
-    
-            KeyEntryMouseReleasedEvent event = new KeyEntryMouseReleasedEvent(this, mouseX, mouseY, buttonId);
-            MinecraftForge.EVENT_BUS.post(event);
-            if(event.isHandled()) {
-                return true;
-            }
-            
-            return this.btnChangeKeyBinding.mouseReleased(mouseX, mouseY, buttonId);
-        }
-        
-        public KeyBinding getKeybinding() {
-            
-            return keybinding;
-        }
-        
-        public String getKeyDesc() {
-            
-            return keyDesc;
-        }
-        
-        public Button getBtnResetKeyBinding() {
-            
-            return btnResetKeyBinding;
-        }
-        
-        public Button getBtnChangeKeyBinding() {
-            
-            return btnChangeKeyBinding;
-        }
-        
-    }
-    
-}

+ 0 - 8
src/main/java/com/blamejared/controlling/client/gui/ISort.java

@@ -1,8 +0,0 @@
-package com.blamejared.controlling.client.gui;
-
-import java.util.List;
-
-public interface ISort {
-    
-    void sort(List<GuiNewKeyBindingList.Entry> entries);
-}

+ 0 - 40
src/main/java/com/blamejared/controlling/client/gui/SortOrder.java

@@ -1,40 +0,0 @@
-package com.blamejared.controlling.client.gui;
-
-import net.minecraft.client.resources.I18n;
-
-import java.util.List;
-
-public enum SortOrder {
-    NONE(entries -> {
-    }), AZ(entries -> {
-        entries.sort((o1, o2) -> ((GuiNewKeyBindingList.KeyEntry) o1).getKeyDesc().compareTo(((GuiNewKeyBindingList.KeyEntry) o2).getKeyDesc()));
-    }), ZA(entries -> {
-        entries.sort((o1, o2) -> ((GuiNewKeyBindingList.KeyEntry) o2).getKeyDesc().compareTo(((GuiNewKeyBindingList.KeyEntry) o1).getKeyDesc()));
-    });
-    
-    private final ISort sorter;
-    
-    SortOrder(ISort sorter) {
-        this.sorter = sorter;
-    }
-    
-    public SortOrder cycle() {
-        return SortOrder.values()[(this.ordinal() + 1) % SortOrder.values().length];
-    }
-    
-    public void sort(List<GuiNewKeyBindingList.Entry> list) {
-        this.sorter.sort(list);
-    }
-    
-    public String getName() {
-        switch(this) {
-            default:
-            case NONE:
-                return I18n.format("options.sortNone");
-            case AZ:
-                return I18n.format("options.sortAZ");
-            case ZA:
-                return I18n.format("options.sortZA");
-        }
-    }
-}

+ 0 - 22
src/main/java/com/blamejared/controlling/events/ClientEventHandler.java

@@ -1,22 +0,0 @@
-package com.blamejared.controlling.events;
-
-import com.blamejared.controlling.client.gui.GuiNewControls;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.screen.ControlsScreen;
-import net.minecraftforge.client.event.GuiOpenEvent;
-import net.minecraftforge.eventbus.api.SubscribeEvent;
-
-public class ClientEventHandler {
-    
-    @SubscribeEvent
-    public void openGui(GuiOpenEvent event) {
-        try {
-            if(event.getGui() instanceof ControlsScreen && !(event.getGui() instanceof GuiNewControls)) {
-                ControlsScreen gui = (ControlsScreen) event.getGui();
-                event.setGui(new GuiNewControls(gui.parentScreen, Minecraft.getInstance().gameSettings));
-            }
-        } catch(Exception e) {
-            e.printStackTrace();
-        }
-    }
-}

+ 0 - 3
src/main/resources/META-INF/accesstransformer.cfg

@@ -1,3 +0,0 @@
-public net.minecraft.client.gui.screen.ControlsScreen field_146494_r # keyBindingList
-public net.minecraft.client.gui.screen.SettingsScreen field_228182_a_ # parentScreen
-public net.minecraft.client.util.InputMappings$Input field_199875_d # REGISTRY

+ 0 - 15
src/main/resources/assets/controlling/lang/kk_kz.json

@@ -1,15 +0,0 @@
-{
-  "options.search": "Іздеу",
-  "options.showAll": "Бәрін көрсету",
-  "options.showConflicts": "Қақтығыс көрсету",
-  "options.showNone": "Байланыспағанды көрсету",
-  "options.availableKeys": "Қолжетімді перне",
-  "options.sort": "Сұрыптау",
-  "options.category": "Санат",
-  "options.key": "Перне",
-  "options.sortNone": "Еш",
-  "options.sortAZ": "A->Z",
-  "options.sortZA": "Z->A",
-  "options.toggleFree": "Бос қосу/өшіру",
-  "options.confirmReset": "Арылтуды растау үшін басыңыз!"
-}

+ 0 - 15
src/main/resources/assets/controlling/lang/ko_kr.json

@@ -1,15 +0,0 @@
-{
-  "options.search": "검색",
-  "options.showAll": "모두 표시",
-  "options.showConflicts": "충돌 표시",
-  "options.showNone": "언바운드 표시",
-  "options.availableKeys": "사용 가능한 키",
-  "options.sort": "정렬",
-  "options.category": "범주",
-  "options.key": "키",
-  "options.sortNone": "없음",
-  "options.sortAZ": "A->Z",
-  "options.sortZA": "Z->A",
-  "options.toggleFree": "자유 설정/해제",
-  "options.confirmReset": "클릭하여 재설정을 확인!"
-}

+ 0 - 6
src/main/resources/pack.mcmeta

@@ -1,6 +0,0 @@
-{
-    "pack": {
-        "description": "controlling resources",
-        "pack_format": 6
-    }
-}