-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP Add reorderstops overlay #889
base: master
Are you sure you want to change the base?
Changes from 4 commits
a7f269b
882f8e2
2a5bac3
068b6a3
44595f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,31 @@ local DIRECTION_MAP = { | |
|
||
local DIRECTION_MAP_REVERSE = utils.invert(DIRECTION_MAP) | ||
|
||
--[[ | ||
- swap 2 elements between different indexes in the same table like: | ||
swap_elements({1, 2, 3}, 1, nil, 3) => {3, 2, 1} | ||
- swap 2 elements at the specified indexes between 2 tables like: | ||
swap_elements({1, 2, 3}, 1, {4, 5, 6}, 3) => {6, 2, 3} {4, 5, 1} | ||
]]-- | ||
local function swap_elements(tbl1, index1, tbl2, index2) | ||
tbl2 = tbl2 or tbl1 | ||
index2 = index2 or index1 | ||
tbl1[index1], tbl2[index2] = tbl2[index2], tbl1[index1] | ||
return tbl1, tbl2 | ||
end | ||
|
||
local function reset_guide_paths(conditions) | ||
for _, condition in ipairs(conditions) do | ||
local gpath = condition.guide_path | ||
|
||
if gpath then | ||
gpath.x:resize(0) | ||
gpath.y:resize(0) | ||
gpath.z:resize(0) | ||
end | ||
end | ||
end | ||
|
||
TrackStopOverlay = defclass(TrackStopOverlay, overlay.OverlayWidget) | ||
TrackStopOverlay.ATTRS{ | ||
default_pos={x=-73, y=29}, | ||
|
@@ -120,7 +145,11 @@ function TrackStopOverlay:setDumpDirection(direction) | |
end | ||
|
||
function TrackStopOverlay:render(dc) | ||
local building = dfhack.gui.getSelectedBuilding() | ||
local building = dfhack.gui.getSelectedBuilding(true) | ||
if not building then | ||
return | ||
end | ||
|
||
local friction = building.friction | ||
local friction_cycle = self.subviews.friction | ||
|
||
|
@@ -201,7 +230,10 @@ function RollerOverlay:setSpeed(speed) | |
end | ||
|
||
function RollerOverlay:render(dc) | ||
local building = dfhack.gui.getSelectedBuilding() | ||
local building = dfhack.gui.getSelectedBuilding(true) | ||
if not building then | ||
return | ||
end | ||
|
||
self.subviews.direction:setOption(DIRECTION_MAP_REVERSE[building.direction]) | ||
self.subviews.speed:setOption(SPEED_MAP_REVERSE[building.speed]) | ||
|
@@ -236,7 +268,197 @@ function RollerOverlay:init() | |
} | ||
end | ||
|
||
ReorderStopsWindow = defclass(ReorderStopsWindow, widgets.Window) | ||
ReorderStopsWindow.ATTRS { | ||
frame={t=4,l=60,w=49, h=26}, | ||
frame_title='Reorder Stops', | ||
resizable=true, | ||
} | ||
|
||
local SELECT_STOP_HINT = 'Select a stop to move' | ||
local SELECT_ANOTHER_STOP_HINT = 'Select another stop to swap or same to cancel' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right click should also cancel out of a partially completed reorder operation. you can do this by handling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
|
||
|
||
function ReorderStopsWindow:handleStopSelection(index, item) | ||
-- Skip routes | ||
if item.type == 'route' then return end | ||
|
||
-- Select stop if none selected | ||
if not self.selected_stop then | ||
self:toggleStopSelection(item) | ||
return | ||
end | ||
|
||
-- Swap stops | ||
self:swapStops(index, item) | ||
|
||
-- Reset stop properties | ||
self:resetStopProperties(item) | ||
|
||
self.selected_stop = nil | ||
self:updateList() | ||
end | ||
|
||
function ReorderStopsWindow:toggleStopSelection(item) | ||
if not self.selected_stop then | ||
self.selected_stop = item | ||
else | ||
self.selected_stop = nil | ||
end | ||
|
||
self:updateList() | ||
end | ||
|
||
function ReorderStopsWindow:swapStops(index, item) | ||
local hauling = df.global.plotinfo.hauling | ||
local routes = hauling.routes | ||
local view_stops = hauling.view_stops | ||
local item_route = routes[item.route_index] | ||
local item_stop_index = item.stop_index | ||
local same_route = self.selected_stop.route_index == item.route_index | ||
|
||
if same_route then | ||
swap_elements(item_route.stops, item_stop_index, nil, self.selected_stop.stop_index) | ||
else | ||
swap_elements( | ||
routes[self.selected_stop.route_index].stops, | ||
self.selected_stop.stop_index, | ||
item_route.stops, | ||
item_stop_index | ||
) | ||
end | ||
|
||
swap_elements(view_stops, self.selected_stop.list_position, nil, index - 1) | ||
end | ||
|
||
function ReorderStopsWindow:resetStopProperties(item) | ||
local hauling = df.global.plotinfo.hauling | ||
local routes = hauling.routes | ||
local item_route = routes[item.route_index] | ||
local same_route = self.selected_stop.route_index == item.route_index | ||
|
||
for i, stop in ipairs(item_route.stops) do | ||
stop.id = i + 1 | ||
reset_guide_paths(stop.conditions) | ||
end | ||
|
||
if not same_route and self.selected_stop then | ||
for i, stop in ipairs(routes[self.selected_stop.route_index].stops) do | ||
stop.id = i + 1 | ||
reset_guide_paths(stop.conditions) | ||
end | ||
end | ||
end | ||
|
||
function ReorderStopsWindow:init() | ||
self.selected_stop = nil | ||
self:addviews{ | ||
widgets.Label{ | ||
frame={t=0,l=0}, | ||
view_id='hint', | ||
text=SELECT_STOP_HINT, | ||
}, | ||
widgets.List{ | ||
view_id='routes', | ||
frame={t=2,l=1}, | ||
choices={}, | ||
on_select=function(_, item) | ||
if not item then return end | ||
if item.type == 'stop' then | ||
local item_pos = df.global.plotinfo.hauling.routes[item.route_index].stops[item.stop_index].pos | ||
dfhack.gui.revealInDwarfmodeMap(item_pos, true, true) | ||
end | ||
end, | ||
on_submit=function(index, item) | ||
self:handleStopSelection(index, item) | ||
end, | ||
}, | ||
} | ||
|
||
self:updateList() | ||
end | ||
|
||
function ReorderStopsWindow:updateList() | ||
local routes = df.global.plotinfo.hauling.routes | ||
local choices = {} | ||
local list_position = 0 | ||
|
||
if self.selected_stop then | ||
self.subviews.hint:setText(SELECT_ANOTHER_STOP_HINT) | ||
else | ||
self.subviews.hint:setText(SELECT_STOP_HINT) | ||
end | ||
|
||
for i, route in ipairs(routes) do | ||
local stops = route.stops | ||
local route_name = route.name | ||
|
||
if route_name == '' then | ||
route_name = 'Route ' .. route.id | ||
end | ||
|
||
table.insert(choices, {text=route_name, type='route', route_index=i, list_position=list_position}) | ||
list_position = list_position + 1 | ||
|
||
for j, stop in ipairs(stops) do | ||
local stop_name = stop.name | ||
|
||
if stop_name == '' then | ||
stop_name = 'Stop ' .. stop.id | ||
end | ||
|
||
if self.selected_stop and self.selected_stop.list_position == list_position then | ||
stop_name = '=> ' .. stop_name | ||
end | ||
|
||
stop_name = ' ' .. stop_name | ||
|
||
table.insert(choices, {text=stop_name, type='stop', stop_index=j, route_index=i, list_position=list_position}) | ||
list_position = list_position + 1 | ||
end | ||
end | ||
|
||
self.subviews.routes:setChoices(choices) | ||
end | ||
|
||
ReorderStopsModal = defclass(ReorderStopsModal, gui.ZScreenModal) | ||
|
||
ReorderStopsModal.ATTRS = { | ||
focus_path = 'ReorderStops', | ||
} | ||
|
||
function ReorderStopsModal:init() | ||
self:addviews{ReorderStopsWindow{}} | ||
end | ||
|
||
function ReorderStopsModal:onDismiss() | ||
df.global.game.main_interface.recenter_indicator_m.x = -30000 | ||
df.global.game.main_interface.recenter_indicator_m.y = -30000 | ||
df.global.game.main_interface.recenter_indicator_m.z = -30000 | ||
end | ||
|
||
ReorderStopsOverlay = defclass(ReorderStopsOverlay, overlay.OverlayWidget) | ||
ReorderStopsOverlay.ATTRS{ | ||
default_pos={x=6, y=6}, | ||
default_enabled=true, | ||
viewscreens='dwarfmode/Hauling', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this specific enough, or should it disappear on hauling subscreens? We might need to extend Gui.cpp if this is the case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like it's okay on all of them except them item selection one. Will fix. |
||
frame={w=30, h=1}, | ||
frame_background=gui.CLEAR_PEN, | ||
} | ||
|
||
function ReorderStopsOverlay:init() | ||
self:addviews{ | ||
widgets.TextButton{ | ||
frame={t=0, l=0}, | ||
label='DFHack reorder stops', | ||
key='CUSTOM_CTRL_E', | ||
on_activate=function() ReorderStopsModal{}:show() end, | ||
}, | ||
} | ||
end | ||
|
||
OVERLAY_WIDGETS = { | ||
trackstop=TrackStopOverlay, | ||
rollers=RollerOverlay, | ||
reorderstops=ReorderStopsOverlay, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this kind of formatting doesn't translate well to the final rendered changelog. each line should be independent. If you start each of them with
`trackstop`:
then they will get combined into a list similar to your intention here