mirror of
https://github.com/TimeCrafters/timecrafters_configuration_tool_desktop.git
synced 2025-12-16 05:42:35 +00:00
Initial implementation of search, updated PacketHandler to behave more more like android app
This commit is contained in:
@@ -41,6 +41,30 @@ module TAC
|
|||||||
@config_changed = false
|
@config_changed = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def move_config(old_name, new_name)
|
||||||
|
if not File.exists?("#{TAC::CONFIGS_PATH}/#{old_name}.json") or
|
||||||
|
File.directory?("#{TAC::CONFIGS_PATH}/#{old_name}.json")
|
||||||
|
# move_config: Can not move config file "#{old_name}" does not exist!
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if File.exists?("#{TAC::CONFIGS_PATH}/#{new_name}.json") &&
|
||||||
|
!File.directory?("#{TAC::CONFIGS_PATH}/#{old_name}.json")
|
||||||
|
# move_config: Config file "#{new_name}" already exist!
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return FileUtils.mv(
|
||||||
|
"#{TAC::CONFIGS_PATH}/#{old_name}.json",
|
||||||
|
"#{TAC::CONFIGS_PATH}/#{new_name}.json"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_config(config_name)
|
||||||
|
FileUtils.rm("#{TAC::CONFIGS_PATH}/#{config_name}.json") if File.exists?("#{TAC::CONFIGS_PATH}/#{config_name}.json")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def upload_config(config_name)
|
def upload_config(config_name)
|
||||||
if @tacnet.connected?
|
if @tacnet.connected?
|
||||||
json = Config.new(config_name).to_json
|
json = Config.new(config_name).to_json
|
||||||
|
|||||||
@@ -7,14 +7,311 @@ module TAC
|
|||||||
menu_bar.clear do
|
menu_bar.clear do
|
||||||
search = edit_line "", width: 0.9, height: 1.0
|
search = edit_line "", width: 0.9, height: 1.0
|
||||||
button get_image("#{TAC::ROOT_PATH}/media/icons/zoom.png"), image_height: 1.0 do
|
button get_image("#{TAC::ROOT_PATH}/media/icons/zoom.png"), image_height: 1.0 do
|
||||||
# do search
|
unless search.value.strip.empty?
|
||||||
body.clear do
|
search_results = search_config(search.value.downcase.strip)
|
||||||
label "Search results for: #{search.value.strip}"
|
|
||||||
label "TODO: Search Results."
|
body.clear do
|
||||||
|
flow(width: 1.0, height: 1.0) do
|
||||||
|
stack(width: 0.495, height: 1.0) do
|
||||||
|
shared_index = 0
|
||||||
|
if search_results.results.size.zero?
|
||||||
|
subtitle "No results for: \"#{search.value.strip}\""
|
||||||
|
else
|
||||||
|
subtitle "Search results for: \"#{search.value.strip}\""
|
||||||
|
end
|
||||||
|
|
||||||
|
if search_results.groups.size.positive?
|
||||||
|
title "Groups"
|
||||||
|
|
||||||
|
search_results.groups.each do |result|
|
||||||
|
stack(width: 1.0, **THEME_ITEM_CONTAINER_PADDING) do
|
||||||
|
background shared_index.even? ? THEME_EVEN_COLOR : THEME_ODD_COLOR
|
||||||
|
button result.highlight(result.group.name), width: 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_index += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if search_results.actions.size.positive?
|
||||||
|
title "Actions"
|
||||||
|
|
||||||
|
search_results.actions.each do |result|
|
||||||
|
stack(width: 1.0, **THEME_ITEM_CONTAINER_PADDING) do
|
||||||
|
background shared_index.even? ? THEME_EVEN_COLOR : THEME_ODD_COLOR
|
||||||
|
button result.highlight(result.action.name), width: 1.0
|
||||||
|
|
||||||
|
if result.from_comment?
|
||||||
|
para result.highlight(result.action.comment), width: 1.0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_index += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if search_results.variables.size.positive?
|
||||||
|
title "Variables"
|
||||||
|
|
||||||
|
search_results.variables.each do |result|
|
||||||
|
stack(width: 1.0, **THEME_ITEM_CONTAINER_PADDING) do
|
||||||
|
background shared_index.even? ? THEME_EVEN_COLOR : THEME_ODD_COLOR
|
||||||
|
button "#{result.highlight(result.variable.name)} [#{result.highlight(result.variable.value)}]", width: 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_index += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
stack(width: 0.495, height: 1.0) do
|
||||||
|
if search_results.group_presets.size.positive?
|
||||||
|
title "Group Presets"
|
||||||
|
|
||||||
|
search_results.group_presets.each do |result|
|
||||||
|
stack(width: 1.0, **THEME_ITEM_CONTAINER_PADDING) do
|
||||||
|
background shared_index.even? ? THEME_EVEN_COLOR : THEME_ODD_COLOR
|
||||||
|
button result.highlight(result.group.name), width: 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_index += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if search_results.action_presets.size.positive?
|
||||||
|
title "Action Presets"
|
||||||
|
|
||||||
|
search_results.action_presets.each do |result|
|
||||||
|
stack(width: 1.0, **THEME_ITEM_CONTAINER_PADDING) do
|
||||||
|
background shared_index.even? ? THEME_EVEN_COLOR : THEME_ODD_COLOR
|
||||||
|
button result.highlight(result.action.name), width: 1.0
|
||||||
|
|
||||||
|
if result.from_comment?
|
||||||
|
para result.highlight(result.action.comment), width: 1.0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_index += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if search_results.variables_from_presets.size.positive?
|
||||||
|
title "Variables from Presets"
|
||||||
|
|
||||||
|
search_results.variables_from_presets.each do |result|
|
||||||
|
stack(width: 1.0, **THEME_ITEM_CONTAINER_PADDING) do
|
||||||
|
background shared_index.even? ? THEME_EVEN_COLOR : THEME_ODD_COLOR
|
||||||
|
button "#{result.highlight(result.variable.name)} [#{result.highlight(result.variable.value)}]", width: 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_index += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def search_config(query)
|
||||||
|
search_results = SearchResults.new
|
||||||
|
|
||||||
|
search_groups(query, search_results)
|
||||||
|
search_actions(query, search_results)
|
||||||
|
search_variables(query, search_results)
|
||||||
|
search_presets(query, search_results)
|
||||||
|
|
||||||
|
return search_results
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_groups(query, search_results)
|
||||||
|
window.backend.config.groups.each do |group|
|
||||||
|
if group.name.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, query: query, is_group: true, is_from_name: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_actions(query, search_results)
|
||||||
|
window.backend.config.groups.each do |group|
|
||||||
|
group.actions.each do |action|
|
||||||
|
if action.name.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, action: action, query: query, is_action: true, is_from_name: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
if action.comment.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, action: action, query: query, is_action: true, is_from_comment: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_variables(query, search_results)
|
||||||
|
window.backend.config.groups.each do |group|
|
||||||
|
group.actions.each do |action|
|
||||||
|
action.variables.each do |variable|
|
||||||
|
if variable.name.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, action: action, variable: variable, is_variable: true, query: query, is_from_name: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
if variable.value.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, action: action, variable: variable, is_variable: true, query: query, is_from_value: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_presets(query, search_results)
|
||||||
|
window.backend.config.presets.groups.each do |group|
|
||||||
|
if group.name.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, query: query, is_group: true, is_from_name: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
group.actions.each do |action|
|
||||||
|
if action.name.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, action: action, query: query, is_action: true, is_from_name: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
if action.comment.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, action: action, query: query, is_action: true, is_from_comment: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
action.variables.each do |variable|
|
||||||
|
if variable.name.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, action: action, variable: variable, is_variable: true, query: query, is_from_name: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
if variable.value.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: group, action: action, variable: variable, is_variable: true, query: query, is_from_value: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
window.backend.config.presets.actions.each do |action|
|
||||||
|
if action.name.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: nil, action: action, query: query, is_action: true, is_from_name: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
if action.comment.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: nil, action: action, query: query, is_action: true, is_from_comment: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
action.variables.each do |variable|
|
||||||
|
if variable.name.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: nil, action: action, variable: variable, is_variable: true, query: query, is_from_name: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
|
||||||
|
if variable.value.downcase.include?(query)
|
||||||
|
result = SearchResult.new(group: nil, action: action, variable: variable, is_variable: true, query: query, is_from_value: true, is_preset: true)
|
||||||
|
search_results.results << result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class SearchResults
|
||||||
|
attr_reader :results
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@results = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def groups
|
||||||
|
@results.select { |result| result.group? && !result.preset? }
|
||||||
|
end
|
||||||
|
|
||||||
|
def actions
|
||||||
|
@results.select { |result| result.action? && !result.preset? }
|
||||||
|
end
|
||||||
|
|
||||||
|
def variables
|
||||||
|
@results.select { |result| result.variable? && !result.preset? }
|
||||||
|
end
|
||||||
|
|
||||||
|
def group_presets
|
||||||
|
@results.select { |result| result.group? && result.preset? }
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_presets
|
||||||
|
@results.select { |result| result.action? && result.preset? }
|
||||||
|
end
|
||||||
|
|
||||||
|
def variables_from_presets
|
||||||
|
@results.select { |result| result.variable? && result.preset? }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class SearchResult
|
||||||
|
attr_reader :group, :action, :variable, :query
|
||||||
|
|
||||||
|
def initialize(query:, group:, action: nil, variable: nil,
|
||||||
|
is_group: false, is_action: false, is_variable: false,
|
||||||
|
is_from_name: false, is_from_value: false, is_from_comment: false, is_preset: false)
|
||||||
|
@group = group
|
||||||
|
@action = action
|
||||||
|
@variable = variable
|
||||||
|
@query = query
|
||||||
|
|
||||||
|
@is_group = is_group
|
||||||
|
@is_action = is_action
|
||||||
|
@is_variable = is_variable
|
||||||
|
|
||||||
|
@is_from_name = is_from_name
|
||||||
|
@is_from_value = is_from_value
|
||||||
|
@is_from_comment = is_from_comment
|
||||||
|
@is_preset = is_preset
|
||||||
|
end
|
||||||
|
|
||||||
|
def group?
|
||||||
|
@is_group
|
||||||
|
end
|
||||||
|
|
||||||
|
def action?
|
||||||
|
@is_action
|
||||||
|
end
|
||||||
|
|
||||||
|
def variable?
|
||||||
|
@is_variable
|
||||||
|
end
|
||||||
|
|
||||||
|
def from_name?
|
||||||
|
@is_from_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def from_value?
|
||||||
|
@is_from_value
|
||||||
|
end
|
||||||
|
|
||||||
|
def from_comment?
|
||||||
|
@is_from_comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def preset?
|
||||||
|
@is_preset
|
||||||
|
end
|
||||||
|
|
||||||
|
def highlight(string)
|
||||||
|
string.gsub(/#{@query}/i, "<b><c=ff00ff>#{@query}</c></b>")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -12,7 +12,7 @@ module TAC
|
|||||||
@animator = CyberarmEngine::Animator.new(start_time: 0, duration: 3_000, from: 0, to: 255)
|
@animator = CyberarmEngine::Animator.new(start_time: 0, duration: 3_000, from: 0, to: 255)
|
||||||
@transition_color = Gosu::Color.new(0x00_000000)
|
@transition_color = Gosu::Color.new(0x00_000000)
|
||||||
|
|
||||||
@next_state = ARGV.include?("--redesign") ? NewEditor : Editor
|
@next_state = USE_REDESIGN ? NewEditor : Editor
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
|
|||||||
@@ -68,40 +68,16 @@ module TAC
|
|||||||
config_name, json = packet.body.split(Packet::PROTOCOL_SEPERATOR, 2)
|
config_name, json = packet.body.split(Packet::PROTOCOL_SEPERATOR, 2)
|
||||||
data = JSON.parse(json, symbolize_names: true)
|
data = JSON.parse(json, symbolize_names: true)
|
||||||
|
|
||||||
if @host_is_a_connection
|
if data.is_a?(Hash) && data.dig(:config, :spec_version) == TAC::CONFIG_SPEC_VERSION
|
||||||
if data.is_a?(Array)
|
File.open("#{TAC::CONFIGS_PATH}/#{config_name}.json", "w") { |f| f.write json }
|
||||||
# OLDEST CONFIG, upgrade?
|
|
||||||
$window.push_state(TAC::Dialog::AlertDialog, title: "Invalid Config", message: "Remote config to old.")
|
|
||||||
|
|
||||||
elsif data.is_a?(Hash) && data.dig(:config, :spec_version) == TAC::CONFIG_SPEC_VERSION
|
|
||||||
File.open("#{TAC::CONFIGS_PATH}/#{config_name}.json", "w") { |f| f.write json }
|
|
||||||
|
|
||||||
if $window.backend.config.name == config_name
|
|
||||||
$window.backend.load_config(config_name)
|
|
||||||
|
|
||||||
$window.instance_variable_get(:"@states").each do |state|
|
|
||||||
state.populate_groups_list if state.is_a?(TAC::States::Editor)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
elsif data.is_a?(Hash) && data.dig(:config, :spec_version) < TAC::CONFIG_SPEC_VERSION
|
|
||||||
# OLD CONFIG, Upgrade?
|
|
||||||
$window.push_state(TAC::Dialog::ConfirmDialog, title: "Upgrade Config", message: "Remote config is an older\nspec version.\nTry to upgrade?", callback_method: proc {})
|
|
||||||
|
|
||||||
elsif data.is_a?(Hash) && data.dig(:config, :spec_version) > TAC::CONFIG_SPEC_VERSION
|
|
||||||
# NEWER CONFIG, Error Out
|
|
||||||
$window.push_state(TAC::Dialog::AlertDialog, title: "Invalid Config", message: "Client outdated, check for\nupdates.\nSupported config spec:\nv#{TAC::CONFIG_SPEC_VERSION} got v#{data.dig(:config, :spec_version)}")
|
|
||||||
|
|
||||||
|
if $window.backend.config&.name == config_name
|
||||||
|
$window.backend.load_config(config_name)
|
||||||
else
|
else
|
||||||
# CONFIG is unknown
|
$window.push_state(TAC::Dialog::AlertDialog, title: "Invalid Config", message: "Supported config spec: v#{TAC::CONFIG_SPEC_VERSION} got v#{data.dig(:config, :spec_version)}")
|
||||||
$window.push_state(TAC::Dialog::AlertDialog, title: "Invalid Config", message: "Remote config is not supported.")
|
end
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
if data.is_a?(Hash) && data.dig(:config, :spec_version) == TAC::CONFIG_SPEC_VERSION
|
|
||||||
File.open("#{TAC::CONFIGS_PATH}/#{config_name}.json", "w") { |f| f.write json }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
rescue JSON::ParserError => e
|
rescue JSON::ParserError => e
|
||||||
log.e(TAG, "JSON parsing error: #{e}")
|
log.e(TAG, "JSON parsing error: #{e}")
|
||||||
end
|
end
|
||||||
@@ -164,15 +140,45 @@ module TAC
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handle_select_config(packet)
|
def handle_select_config(packet)
|
||||||
|
config_name = packet.body
|
||||||
|
|
||||||
|
$window.backend.settings.config = config_name
|
||||||
|
$window.backend.save_settings
|
||||||
|
$window.backend.load_config(config_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_add_config(packet)
|
def handle_add_config(packet)
|
||||||
|
config_name = packet.body
|
||||||
|
|
||||||
|
if $window.backend.configs_list.include?(config_name)
|
||||||
|
unless @host_is_a_connection
|
||||||
|
if $server.active_client&.connected?
|
||||||
|
$server.active_client.puts(PacketHandler.packet_error("Config already exists!", "A config with the name #{config_name} already exists over here."))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
$window.backend.write_new_config(config_name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_update_config(packet)
|
def handle_update_config(packet)
|
||||||
|
old_config_name, new_config_name = packet.body.split(PROTOCOL_SEPERATOR, 2)
|
||||||
|
|
||||||
|
if $window.backend.configs_list.include?(config_name)
|
||||||
|
unless @host_is_a_connection
|
||||||
|
if $server.active_client&.connected?
|
||||||
|
$server.active_client.puts(PacketHandler.packet_error("Config already exists!", "A config with the name #{config_name} already exists over here."))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
$window.backend.move_config(old_config_name, new_config_name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_delete_config(packet)
|
def handle_delete_config(packet)
|
||||||
|
config_name = packet.body
|
||||||
|
|
||||||
|
$window.backend.delete_config(config_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.packet_handshake(client_uuid)
|
def self.packet_handshake(client_uuid)
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ require_relative "lib/tacnet/server"
|
|||||||
|
|
||||||
# Thread.abort_on_exception = true
|
# Thread.abort_on_exception = true
|
||||||
|
|
||||||
|
USE_REDESIGN = ARGV.include?("--redesign")
|
||||||
|
|
||||||
if not defined?(Ocra)
|
if not defined?(Ocra)
|
||||||
TAC::Window.new(width: (Gosu.screen_width * 0.8).round, height: (Gosu.screen_height * 0.8).round, resizable: true, borderless: true).show
|
TAC::Window.new(width: (Gosu.screen_width * 0.8).round, height: (Gosu.screen_height * 0.8).round, resizable: true, borderless: USE_REDESIGN).show
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user