|
|
|
|
|
if FirstLoad then |
|
LocalStorage.LocalCS = LocalStorage.LocalCS or {} |
|
end |
|
|
|
function GetLocalCS() |
|
local dialog = GetDialog("XSelectObjectsTool") or GetDialog("XPlaceObjectTool") |
|
local helper = dialog and g_Classes[dialog.helper_class] |
|
if helper and helper.HasLocalCSSetting then return LocalStorage.LocalCS[helper.class] end |
|
end |
|
|
|
function SetLocalCS(localCS) |
|
local dialog = GetDialog("XSelectObjectsTool") or GetDialog("XPlaceObjectTool") |
|
local helper = dialog and g_Classes[dialog.helper_class] |
|
if helper and helper.HasLocalCSSetting then |
|
LocalStorage.LocalCS[helper.class] = localCS |
|
dialog:UpdatePlacementHelper() |
|
SaveLocalStorage() |
|
end |
|
end |
|
|
|
|
|
|
|
|
|
local snap_modes = { |
|
{ id = "20cm/15°", description = "Fine snapping", xy = 20*guic, angle = 15 * 60 }, |
|
{ id = "1m/90°", description = "Meter snapping", xy = guim, angle = 90 * 60 }, |
|
{ id = "Passability", description = "Snap to passability grid", xy = const.PassTileSize }, |
|
{ id = "Custom", description = "Custom snapping", }, |
|
} |
|
if const.SlabSizeX then |
|
table.insert(snap_modes, { id = "Voxels", description = "Snap to voxels/slabs", xy = const.SlabSizeX, z = const.SlabSizeZ, angle = 90 * 60, center = true }) |
|
end |
|
if const.HexWidth then |
|
table.insert(snap_modes, { id = "HexGrid", description = "Snap to hex grid", angle = 60 * 60 }) |
|
end |
|
if const.BuildLevelHeight then |
|
table.insert(snap_modes, { id = "BuildLevel", description = "Snap to build levels", z = const.BuildLevelHeight }) |
|
end |
|
for i, item in ipairs(snap_modes) do |
|
item.shortcut = i == 1 and "Alt-~" or "Alt-" .. string.char(48 + i - 1) |
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
function OnMsg.Autorun() |
|
EditorSettings = XEditorSettings:new() |
|
EditorSettingsGedThread = false |
|
end |
|
|
|
local rightclick_items = { |
|
{ id = "ContextMenu", name = "Open context menu" }, |
|
{ id = "ObjectProps", name = "Open object properties" }, |
|
} |
|
|
|
DefineClass.XEditorSettings = { |
|
__parents = { "XEditorToolSettings" }, |
|
properties = { |
|
persisted_setting = true, auto_select_all = true, |
|
{ category = "General", id = "AutosaveTime", name = "Autosave time (min)", editor = "number", default = 0, min = 0, max = 30, slider = true, help = "Set to zero to disable map autosaves.", |
|
no_edit = config.ModdingToolsInUserMode, |
|
}, |
|
{ category = "General", id = "ShowPlayArea", name = "Show play area", editor = "bool", default = true }, |
|
{ category = "General", id = "CloudShadows", name = "Show cloud shadows", editor = "bool", default = false }, |
|
{ category = "General", id = "TestParticlesOnChange", name = "Replay particles on edit", editor = "bool", default = false }, |
|
{ category = "General", id = "TestParticlesOnChangeHelp", editor = "help", help = "(replay with Shift-E or Z, Alt-E toggles this)" }, |
|
{ category = "UI", id = "AutoFocusMenuSearch", editor = "bool", name = "Auto focus ~ menu search", default = true }, |
|
{ category = "UI", id = "SmartSelection", name = "Smart selection", editor = "bool", default = true, help = "If no object is found at the precise position of the cursor, search for one by bounding box too." }, |
|
{ category = "UI", id = "HighlightOnHover", name = "Highlight on hover", editor = "bool", default = true }, |
|
{ category = "UI", id = "FilterHighlight", name = "Highlight on filter hover", editor = "bool", default = true }, |
|
{ category = "UI", id = "RightClickOpens", name = "RightClick", editor = "combo", default = "ContextMenu", items = rightclick_items }, |
|
{ category = "UI", id = "CtrlRightClickOpens", name = "Ctrl-RightClick", editor = "combo", default = "ObjectProps", items = rightclick_items, read_only = true, persisted_setting = false }, |
|
{ category = "UI", id = "EditorToolbar", name = "Editor toolbar", editor = "bool", default = true }, |
|
{ category = "UI", id = "DarkMode", name = "Dark mode", editor = "choice", default = "Follow system", items = { "Follow system", "Dark", "Light" } }, |
|
{ category = "UI", id = "MessageBoxFont", name = "Message box font", editor = "choice", default = "Tahoma", items = { { name = "Tahoma (clasic)", value = "Tahoma" }, { name = "Consolas (monospace)", value = "Consolas" } }, |
|
no_edit = config.ModdingToolsInUserMode, |
|
}, |
|
{ category = "Ged (external editor windows)", id = "GedUIScale", name = "UI scale", editor = "number", min = 75, max = 200, slider = true, default = 100, step = 1 }, |
|
{ category = "Ged (external editor windows)", id = "ColorPickerScale", name = "Color picker scale", editor = "number", min = 100, max = 200, slider = true, default = 100, step = 1 }, |
|
{ category = "Ged (external editor windows)", id = "LimitObjectEditorItems", name = "Limit items in Object editor", editor = "bool", default = true, help = "Only the first 500 objects in the selection will be visible and editable in the Object editor for better performance." }, |
|
{ category = "Gizmos", id = "GizmoThickness", name = "Thickness", editor = "number", min = 25, max = 100, slider = true, default = 75, step = 1 }, |
|
{ category = "Gizmos", id = "GizmoOpacity", name = "Opacity", editor = "number", min = 32, max = 255, slider = true, default = 110, step = 1 }, |
|
{ category = "Gizmos", id = "GizmoScale", name = "Scale", editor = "number", min = 25, max = 100, slider = true, default = 85, step = 1 }, |
|
{ category = "Gizmos", id = "GizmoSensitivity", name = "Active area size", editor = "number", min = 50, max = 200, slider = true, default = 100, step = 1, help = "Adjusts the size of the area where you can grab a gizmo control element, e.g. axis." }, |
|
{ category = "Gizmos", id = "GizmoRotateSnapping", name = "Snap angle in Rotate Gizmo", editor = "bool", default = true, }, |
|
|
|
|
|
{ id = "SnapEnabled", editor = "bool", default = false, no_edit = true }, |
|
{ id = "SnapMode", editor = "choice", items = snap_modes, default = "", no_edit = true, }, |
|
{ id = "SnapXY", editor = "number", default = 0, no_edit = true, }, |
|
{ id = "SnapZ", editor = "number", default = 0, no_edit = true, }, |
|
{ id = "SnapAngle", editor = "number", default = 0, no_edit = true, }, |
|
}, |
|
ged = false, |
|
should_open = false, |
|
} |
|
|
|
function XEditorSettings:GetCtrlRightClickOpens() |
|
return self:GetRightClickOpens() == "ContextMenu" and "ObjectProps" or "ContextMenu" |
|
end |
|
|
|
function XEditorSettings:GetSnapModes() |
|
return snap_modes |
|
end |
|
|
|
function XEditorSettings:PosSnap(pos, by_slabs) |
|
local snap_mode = table.find_value(snap_modes, "id", self:GetSnapMode()) |
|
|
|
if not by_slabs then |
|
if not self:GetSnapEnabled() or not snap_mode then |
|
return pos |
|
end |
|
if snap_mode.id == "Voxels" then |
|
return SnapToVoxel(pos + point(0, 0, const.SlabSizeZ / 2)) |
|
end |
|
if snap_mode.id == "HexGrid" then |
|
return HexGetNearestCenter(pos) |
|
end |
|
end |
|
|
|
local center |
|
local x, y, z = pos:xyz() |
|
local sx, sy, sz = self:GetSnapXY(), self:GetSnapXY(), self:GetSnapZ() |
|
if by_slabs then |
|
sx, sy, sz = const.SlabSizeX, const.SlabSizeY, const.SlabSizeZ |
|
else |
|
center = snap_mode.center |
|
end |
|
if sx > 0 and sy > 0 then |
|
if center then x, y = x - sx / 2, y - sy / 2 end |
|
x = (x + sx / 2) / sx * sx |
|
y = (y + sy / 2) / sy * sy |
|
if center then x, y = x + sx / 2, y + sy / 2 end |
|
end |
|
if sz > 0 then |
|
z = z or terrain.GetHeight(pos) |
|
z = (z + sz / 2) / sz * sz |
|
end |
|
return point(x, y, z) |
|
end |
|
|
|
function XEditorSettings:AngleSnap(angle, by_slabs) |
|
local sa = by_slabs and 90 * 60 or self:GetSnapEnabled() and self:GetSnapAngle() or 0 |
|
if sa ~= 0 then |
|
angle = (angle + sa / 2) / sa * sa |
|
end |
|
return angle |
|
end |
|
|
|
function XEditorSettings:OnEditorSetProperty(prop_id, old_value, ged) |
|
if prop_id == "AutosaveTime" then |
|
EditorAutosaveNextTime = now() + self:GetAutosaveTime() * 60 * 1000 |
|
EditorCreateAutosaveThread() |
|
elseif prop_id == "CloudShadows" then |
|
hr.EnableCloudsShadow = self:GetCloudShadows() and 1 or 0 |
|
elseif prop_id == "EditorToolbar" and GetDialog("XEditorToolbar") then |
|
GetDialog("XEditorToolbar"):SetVisible(self:GetEditorToolbar()) |
|
elseif prop_id == "DarkMode" then |
|
for id, dlg in pairs(Dialogs) do |
|
if IsKindOf(dlg, "XDarkModeAwareDialog") then |
|
dlg:SetDarkMode(GetDarkModeSetting()) |
|
end |
|
end |
|
for id, socket in pairs(GedConnections) do |
|
socket:Send("rfnApp", "SetDarkMode", GetDarkModeSetting()) |
|
end |
|
ReloadShortcuts() |
|
elseif prop_id == "MessageBoxFont" then |
|
config.MessageBoxFont = self:GetProperty(prop_id) |
|
elseif prop_id == "SnapMode" then |
|
local mode = self:GetSnapMode() |
|
if mode ~= "Custom" and mode ~= "" then |
|
local mode = table.find_value(snap_modes, "id", mode) |
|
self:SetSnapXY(mode.xy) |
|
self:SetSnapZ(mode.z) |
|
self:SetSnapAngle(mode.angle) |
|
end |
|
self:SetSnapEnabled(true) |
|
local dialog = GetDialog("XSelectObjectsTool") or GetDialog("XPlaceObjectTool") |
|
if dialog then dialog:UpdatePlacementHelper() end |
|
XEditorUpdateToolbars() |
|
end |
|
Msg("EditorSettingChanged", prop_id, self:GetProperty(prop_id)) |
|
end |
|
|
|
function XEditorSettings:OnShortcut(shortcut, source, ...) |
|
local dialog = GetDialog("XSelectObjectsTool") or GetDialog("XPlaceObjectTool") |
|
local helper = dialog and g_Classes[dialog.helper_class] |
|
if shortcut == "X" and helper and helper.HasSnapSetting then |
|
XEditorSettings:SetSnapEnabled(not XEditorSettings:GetSnapEnabled()) |
|
XEditorUpdateToolbars() |
|
return "break" |
|
end |
|
for _, mode in ipairs(snap_modes) do |
|
if shortcut == mode.shortcut and helper and helper.HasSnapSetting then |
|
XEditorSettings:SetSnapMode(mode.id) |
|
XEditorSettings:OnEditorSetProperty("SnapMode") |
|
XEditorUpdateToolbars() |
|
return "break" |
|
end |
|
end |
|
return XEditorTool.OnShortcut(self, shortcut, source, ...) |
|
end |
|
|
|
function XEditorSettings:ToggleGedEditor() |
|
self.should_open = not self.should_open |
|
|
|
if not IsValidThread(EditorSettingsGedThread) then |
|
EditorSettingsGedThread = CreateRealTimeThread(function() |
|
while true do |
|
if not self.ged and self.should_open then |
|
self.ged = OpenGedApp("XEditorSettings", EditorSettings, nil, "XEditorSettings", true) |
|
elseif self.ged and not self.should_open then |
|
CloseGedApp(self.ged, "wait") |
|
self.ged = false |
|
end |
|
Sleep(100) |
|
end |
|
end) |
|
end |
|
end |
|
|