mirror of
https://github.com/TimeCrafters/timecrafters_configuration_tool_desktop.git
synced 2025-12-16 22:02:34 +00:00
Compare commits
11 Commits
4bdc12ce46
...
v0.8.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 86c1f24337 | |||
| 3aa63b4ad1 | |||
| abdb86440f | |||
| b8cb9b9ab8 | |||
| c4622fa563 | |||
| d49938855d | |||
| 6554140acf | |||
| 43510faaa2 | |||
| 3350f4f063 | |||
| 49133bb49d | |||
| 8aaed6bc8d |
7
Gemfile
7
Gemfile
@@ -1,9 +1,8 @@
|
|||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
gem "cyberarm_engine"
|
gem "cyberarm_engine"
|
||||||
gem "gosu_notifications"
|
|
||||||
|
|
||||||
group :packaging do
|
group :packaging do
|
||||||
gem "ocra"
|
gem "ocran"
|
||||||
gem "releasy"
|
# gem "releasy", path: "../releasy"
|
||||||
end
|
end
|
||||||
|
|||||||
22
Gemfile.lock
22
Gemfile.lock
@@ -1,33 +1,21 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
cri (2.1.0)
|
cyberarm_engine (0.24.1)
|
||||||
cyberarm_engine (0.23.0)
|
|
||||||
excon (~> 0.88)
|
excon (~> 0.88)
|
||||||
gosu (~> 1.1)
|
gosu (~> 1.1)
|
||||||
gosu_more_drawables (~> 0.3)
|
gosu_more_drawables (~> 0.3)
|
||||||
excon (0.104.0)
|
excon (0.109.0)
|
||||||
gosu (1.4.6)
|
gosu (1.4.6)
|
||||||
gosu_more_drawables (0.3.1)
|
gosu_more_drawables (0.3.1)
|
||||||
gosu_notifications (0.1.0)
|
ocran (1.3.15)
|
||||||
ocra (1.3.11)
|
|
||||||
rake (13.1.0)
|
|
||||||
releasy (0.2.3)
|
|
||||||
bundler (>= 1.2.1)
|
|
||||||
cri (~> 2.1.0)
|
|
||||||
ocra (~> 1.3.0)
|
|
||||||
rake (>= 0.9.2.2)
|
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
x64-mingw-ucrt
|
x64-mingw-ucrt
|
||||||
x64-mingw32
|
|
||||||
x86_64-linux
|
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
cyberarm_engine
|
cyberarm_engine
|
||||||
gosu_notifications
|
ocran
|
||||||
ocra
|
|
||||||
releasy
|
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.4.3
|
2.5.3
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ module TAC
|
|||||||
@config_files_list = @config_files.map { |file| Dialog::NamePromptDialog::NameStub.new(File.basename(file, ".json")) }
|
@config_files_list = @config_files.map { |file| Dialog::NamePromptDialog::NameStub.new(File.basename(file, ".json")) }
|
||||||
|
|
||||||
@configs_list.clear do
|
@configs_list.clear do
|
||||||
@config_files.each_with_index do |config_file, i|
|
@config_files.sort_by { |f| [f.downcase] }.each_with_index do |config_file, i|
|
||||||
flow width: 1.0, height: 36, **THEME_ITEM_CONTAINER_PADDING do
|
flow width: 1.0, height: 36, **THEME_ITEM_CONTAINER_PADDING do
|
||||||
name = File.basename(config_file, ".json")
|
name = File.basename(config_file, ".json")
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,27 @@ module TAC
|
|||||||
@actions_menu = flow(width: 1.0, height: 36) do
|
@actions_menu = flow(width: 1.0, height: 36) do
|
||||||
label "Actions", text_size: THEME_SUBHEADING_TEXT_SIZE, fill: true, text_align: :center
|
label "Actions", text_size: THEME_SUBHEADING_TEXT_SIZE, fill: true, text_align: :center
|
||||||
|
|
||||||
button get_image("#{TAC::MEDIA_PATH}/icons/plus.png"), image_width: THEME_ICON_SIZE, tip: "Add action" do
|
# TODO: Implement this
|
||||||
|
# button get_image("#{TAC::MEDIA_PATH}/icons/barsHorizontal.png"), image_width: THEME_ICON_SIZE, tip: "Auto renumber engine actions", margin_right: 16, enabled: false do
|
||||||
|
# end
|
||||||
|
|
||||||
|
button get_image("#{TAC::MEDIA_PATH}/icons/up.png"), image_width: THEME_ICON_SIZE, tip: "Move selected action up (and its children, if holding SHIFT)" do
|
||||||
|
if @active_group && @active_action
|
||||||
|
shift_action(@active_action, :up)
|
||||||
|
else
|
||||||
|
push_state(TAC::Dialog::AlertDialog, title: "Error", message: "Unable to shift action, no action selected.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
button get_image("#{TAC::MEDIA_PATH}/icons/down.png"), image_width: THEME_ICON_SIZE, tip: "Move selected action down (and its children, if holding SHIFT)" do
|
||||||
|
if @active_group && @active_action
|
||||||
|
shift_action(@active_action, :down)
|
||||||
|
else
|
||||||
|
push_state(TAC::Dialog::AlertDialog, title: "Error", message: "Unable to shift action, no action selected.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
button get_image("#{TAC::MEDIA_PATH}/icons/plus.png"), image_width: THEME_ICON_SIZE, tip: "Add action", margin_left: 16 do
|
||||||
if @active_group
|
if @active_group
|
||||||
push_state(TAC::Dialog::ActionDialog, title: "Create Action", list: @active_group.actions, callback_method: method(:create_action))
|
push_state(TAC::Dialog::ActionDialog, title: "Create Action", list: @active_group.actions, callback_method: method(:create_action))
|
||||||
else
|
else
|
||||||
@@ -170,7 +190,7 @@ module TAC
|
|||||||
button get_image("#{TAC::MEDIA_PATH}/icons/import.png"), image_width: THEME_ICON_SIZE, tip: "Import action from preset" do
|
button get_image("#{TAC::MEDIA_PATH}/icons/import.png"), image_width: THEME_ICON_SIZE, tip: "Import action from preset" do
|
||||||
if @active_group
|
if @active_group
|
||||||
push_state(Dialog::PickPresetDialog, title: "Pick Action Preset", limit: :actions, callback_method: proc { |preset|
|
push_state(Dialog::PickPresetDialog, title: "Pick Action Preset", limit: :actions, callback_method: proc { |preset|
|
||||||
push_state(Dialog::ActionDialog, title: "Name Action", action: preset, accept_label: "Add", list: @active_group.actions, callback_method: proc { |action, name, comment|
|
push_state(Dialog::ActionDialog, title: "Name Action", action: preset, cloning: true, accept_label: "Add", list: @active_group.actions, callback_method: proc { |action, name, comment|
|
||||||
clone = TAC::Config::Action.from_json( JSON.parse( action.to_json, symbolize_names: true ))
|
clone = TAC::Config::Action.from_json( JSON.parse( action.to_json, symbolize_names: true ))
|
||||||
clone.name = name.to_s
|
clone.name = name.to_s
|
||||||
clone.comment = comment.to_s
|
clone.comment = comment.to_s
|
||||||
@@ -377,6 +397,12 @@ module TAC
|
|||||||
comment_label.value = comment.to_s
|
comment_label.value = comment.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if action_is_child?(action)
|
||||||
|
action_container.style.default[:margin_left] = 72
|
||||||
|
else
|
||||||
|
action_container.style.default[:margin_left] = 0
|
||||||
|
end
|
||||||
|
|
||||||
action_container.style.tag = name
|
action_container.style.tag = name
|
||||||
|
|
||||||
update_list_children(@actions_list)
|
update_list_children(@actions_list)
|
||||||
@@ -565,7 +591,10 @@ module TAC
|
|||||||
def add_action_container(action)
|
def add_action_container(action)
|
||||||
index = @active_group.actions.index(action)
|
index = @active_group.actions.index(action)
|
||||||
|
|
||||||
stack width: 1.0, height: action.comment.empty? ? 36 : 72, **THEME_ITEM_CONTAINER_PADDING, tag: action.name do |container|
|
# Determine whether we should intent this action's container element because it is for a child state (i.e. 00-01)
|
||||||
|
indent = action_is_child?(action)
|
||||||
|
|
||||||
|
stack width: 1.0, height: action.comment.empty? ? 36 : 72, **THEME_ITEM_CONTAINER_PADDING, margin_left: indent ? 72 : 0, tag: action.name do |container|
|
||||||
background action == @active_action ? THEME_HIGHLIGHTED_COLOR : (index.even? ? THEME_EVEN_COLOR : THEME_ODD_COLOR)
|
background action == @active_action ? THEME_HIGHLIGHTED_COLOR : (index.even? ? THEME_EVEN_COLOR : THEME_ODD_COLOR)
|
||||||
@active_action_container = container if action == @active_action
|
@active_action_container = container if action == @active_action
|
||||||
|
|
||||||
@@ -622,6 +651,176 @@ module TAC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def shift_action(action, direction)
|
||||||
|
# Determine whether this action is named as required for this operation
|
||||||
|
valid_name = valid_engine_action_name?(action)
|
||||||
|
am_child = action_is_child?(action)
|
||||||
|
index = @active_group.actions.index(action)
|
||||||
|
move_children = shift_down? # require that a SHIFT key is down when moving childen with their current parent to prevent undesired relocations.
|
||||||
|
|
||||||
|
unless valid_name
|
||||||
|
push_state(TAC::Dialog::AlertDialog, title: "Error", message: "Unable to shift action, incorrectly formated name.\nExpected: name to be like '00-00' not '#{action.name}'")
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
base_int = valid_name[0]
|
||||||
|
subbase_int = valid_name[1]
|
||||||
|
|
||||||
|
return if direction == :up && index.zero?
|
||||||
|
|
||||||
|
index_before = index - 1 >= 0 ? index - 1 : nil
|
||||||
|
index_next = index + 1 < @active_group.actions.size ? index + 1 : nil
|
||||||
|
|
||||||
|
mutated = false
|
||||||
|
|
||||||
|
case direction
|
||||||
|
when :up
|
||||||
|
if index_before
|
||||||
|
other = @active_group.actions[index_before]
|
||||||
|
other_is_child = action_is_child?(other)
|
||||||
|
|
||||||
|
i = index
|
||||||
|
|
||||||
|
while(other && ((!am_child && other_is_child) || (am_child && !other_is_child)))
|
||||||
|
i -= 1
|
||||||
|
index_before = i - 1 >= 0 ? i - 1 : nil
|
||||||
|
|
||||||
|
return unless index_before
|
||||||
|
return if am_child && valid_engine_action_name?(other).to_a[0].to_i != base_int
|
||||||
|
|
||||||
|
other = @active_group.actions[index_before]
|
||||||
|
other_is_child = action_is_child?(other)
|
||||||
|
end
|
||||||
|
|
||||||
|
move_child_actions(other, action) if move_children
|
||||||
|
swap_action(action, other)
|
||||||
|
mutated = true
|
||||||
|
end
|
||||||
|
when :down
|
||||||
|
if index_next
|
||||||
|
other = @active_group.actions[index_next]
|
||||||
|
other_is_child = action_is_child?(other)
|
||||||
|
|
||||||
|
i = index
|
||||||
|
|
||||||
|
while(other && ((!am_child && other_is_child) || (am_child && !other_is_child)))
|
||||||
|
i += 1
|
||||||
|
index_next = i + 1 < @active_group.actions.size ? i + 1 : nil
|
||||||
|
|
||||||
|
return unless index_next
|
||||||
|
return if am_child && valid_engine_action_name?(other).to_a[0].to_i != base_int
|
||||||
|
|
||||||
|
other = @active_group.actions[index_next]
|
||||||
|
other_is_child = action_is_child?(other)
|
||||||
|
end
|
||||||
|
|
||||||
|
move_child_actions(action, other) if move_children
|
||||||
|
swap_action(action, other)
|
||||||
|
mutated = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return unless mutated
|
||||||
|
|
||||||
|
@active_group.actions.sort_by! { |a| a.name.downcase }
|
||||||
|
|
||||||
|
window.backend.config_changed!
|
||||||
|
|
||||||
|
@active_action_label.value = action.name
|
||||||
|
|
||||||
|
update_list_children(@actions_list)
|
||||||
|
|
||||||
|
scroll_into_view(action)
|
||||||
|
end
|
||||||
|
|
||||||
|
def swap_action(action, other)
|
||||||
|
old_name = action.name
|
||||||
|
new_name = other.name
|
||||||
|
|
||||||
|
action.name = other.name
|
||||||
|
other.name = old_name
|
||||||
|
|
||||||
|
action_container = find_element_by_tag(@actions_list, old_name)
|
||||||
|
action_label = find_element_by_tag(action_container, "label")
|
||||||
|
|
||||||
|
other_container = find_element_by_tag(@actions_list, new_name)
|
||||||
|
other_label = find_element_by_tag(other_container, "label")
|
||||||
|
|
||||||
|
action_container.style.tag = action.name
|
||||||
|
other_container.style.tag = other.name
|
||||||
|
action_label.value = action.name
|
||||||
|
other_label.value = other.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def move_child_actions(action, other)
|
||||||
|
# Ordered: OTHER, ACTION
|
||||||
|
children = [select_child_actions(other), select_child_actions(action)]
|
||||||
|
|
||||||
|
[action, other].each_with_index do |a, i|
|
||||||
|
new_base_int, _new_subbase_int = valid_engine_action_name?(a)
|
||||||
|
|
||||||
|
children[i].each do |child|
|
||||||
|
child_base_int, child_subbase_int = valid_engine_action_name?(child)
|
||||||
|
|
||||||
|
# puts format("MOVING CHILD: #{child.name} (#{child.comment}) from %02d-00 to %02d-00", child_base_int, new_base_int)
|
||||||
|
new_name = format("%02d-%02d", new_base_int, child_subbase_int)
|
||||||
|
|
||||||
|
action_container = find_element_by_tag(@actions_list, child.name)
|
||||||
|
action_label = find_element_by_tag(action_container, "label")
|
||||||
|
|
||||||
|
action_container.style.tag = new_name
|
||||||
|
action_label.value = new_name
|
||||||
|
|
||||||
|
child.name = new_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_child_actions(action)
|
||||||
|
valid_name = valid_engine_action_name?(action)
|
||||||
|
|
||||||
|
@active_group.actions.select do |a|
|
||||||
|
child_base_int, _child_subbase_int = valid_engine_action_name?(a)
|
||||||
|
|
||||||
|
next unless child_base_int
|
||||||
|
|
||||||
|
child_base_int == valid_name[0] && action_is_child?(a)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid_engine_action_name?(action)
|
||||||
|
base, subbase = action.name.split("-", 2)
|
||||||
|
base_int = -1
|
||||||
|
subbase_int = -1
|
||||||
|
|
||||||
|
return false unless base && subbase
|
||||||
|
|
||||||
|
return false unless base.length == 2 && subbase.length == 2
|
||||||
|
|
||||||
|
# Work around bug in Ruby's `Integer("08")` parser
|
||||||
|
base = base[0] == "0" ? base[1] : base
|
||||||
|
subbase = subbase[0] == "0" ? subbase[1] : subbase
|
||||||
|
|
||||||
|
begin
|
||||||
|
base_int = Integer(base)
|
||||||
|
subbase_int = Integer(subbase)
|
||||||
|
rescue ArgumentError
|
||||||
|
base_int = -1
|
||||||
|
subbase_int = -1
|
||||||
|
end
|
||||||
|
|
||||||
|
return [base_int, subbase_int] if base_int >= 0 && subbase_int >= 0
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_is_child?(action)
|
||||||
|
_base_int, subbase_int = valid_engine_action_name?(action)
|
||||||
|
|
||||||
|
return (subbase_int && subbase_int > 0) ? true : false
|
||||||
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
super
|
super
|
||||||
|
|
||||||
@@ -629,7 +828,7 @@ module TAC
|
|||||||
item = @highlight_item_container
|
item = @highlight_item_container
|
||||||
|
|
||||||
Gosu.draw_rect(
|
Gosu.draw_rect(
|
||||||
item.x, item.y,
|
item.x, item.y + (item&.parent&.scroll_top || 0),
|
||||||
item.width, item.height,
|
item.width, item.height,
|
||||||
@highlight_animator.color_transition,
|
@highlight_animator.color_transition,
|
||||||
item.z + 1
|
item.z + 1
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
module TAC
|
module TAC
|
||||||
NAME = "TimeCrafters Configuration Tool"
|
NAME = "TimeCrafters Configuration Tool"
|
||||||
VERSION = "0.7.2"
|
RELEASE_DATE = "2024-01-19" # ISO 8601 Date of version release
|
||||||
RELEASE_NAME = "Beta"
|
VERSION = "0.8.0"
|
||||||
|
RELEASE_NAME = "BETA"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ module TAC
|
|||||||
def initialize(**args)
|
def initialize(**args)
|
||||||
super(**args)
|
super(**args)
|
||||||
|
|
||||||
self.caption = "#{TAC::NAME} v#{TAC::VERSION} (#{TAC::RELEASE_NAME})"
|
self.caption = "#{TAC::NAME} v#{TAC::VERSION} (#{TAC::RELEASE_NAME}) [#{TAC::RELEASE_DATE}]"
|
||||||
@backend = Backend.new
|
@backend = Backend.new
|
||||||
@notification_manager = CyberarmEngine::NotificationManager.new(window: self, edge: :bottom)
|
@notification_manager = CyberarmEngine::NotificationManager.new(window: self, edge: :bottom)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
begin
|
begin
|
||||||
raise LoadError if defined?(Ocra)
|
raise LoadError if defined?(Ocra) || defined?(Ocran)
|
||||||
require_relative "../cyberarm_engine/lib/cyberarm_engine"
|
require_relative "../cyberarm_engine/lib/cyberarm_engine"
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
require "cyberarm_engine"
|
require "cyberarm_engine"
|
||||||
@@ -73,7 +73,7 @@ require_relative "lib/game_clock/net/packet"
|
|||||||
USE_REDESIGN = ARGV.include?("--redesign")
|
USE_REDESIGN = ARGV.include?("--redesign")
|
||||||
BORDERLESS = ARGV.include?("--borderless")
|
BORDERLESS = ARGV.include?("--borderless")
|
||||||
|
|
||||||
if not defined?(Ocra)
|
unless defined?(Ocra) || defined?(Ocran)
|
||||||
TAC::Window.new(width: (Gosu.screen_width * 0.8).round, height: (Gosu.screen_height * 0.8).round, resizable: true, borderless: BORDERLESS).show
|
TAC::Window.new(width: (Gosu.screen_width * 0.8).round, height: (Gosu.screen_height * 0.8).round, resizable: true, borderless: BORDERLESS).show
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user