Skip to content

Commit 4b5be79

Browse files
committed
Highlight all
1 parent b9c82f6 commit 4b5be79

1 file changed

Lines changed: 67 additions & 37 deletions

File tree

plugins/lua/orders.lua

Lines changed: 67 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,8 @@ end
717717
local search_cursor_visible = false
718718
local search_last_scroll_position = -1
719719
local order_count_at_highlight = 0
720+
local search_matched_indices = {}
721+
local search_current_match_idx = 0
720722

721723
local function perform_search(text)
722724
local matches = {}
@@ -812,15 +814,12 @@ function OrdersSearchOverlay:init()
812814
minimized_panel,
813815
}
814816

815-
-- Initialize search state
816-
self.matched_indices = {}
817-
self.current_match_idx = 0
818817
self.minimized = false
819818
end
820819

821820
function OrdersSearchOverlay:update_filter(text)
822-
self.matched_indices = perform_search(text)
823-
self.current_match_idx = 0
821+
search_matched_indices = perform_search(text)
822+
search_current_match_idx = 0
824823
search_cursor_visible = false
825824

826825
if text == '' then
@@ -846,26 +845,26 @@ function OrdersSearchOverlay:cycle_match(direction)
846845
local new_matches = perform_search(search_text)
847846

848847
if #new_matches == 0 then
849-
self.matched_indices = {}
850-
self.current_match_idx = 0
848+
search_matched_indices = {}
849+
search_current_match_idx = 0
851850
search_cursor_visible = false
852851
self.subviews.main_panel.frame_title = 'Search'
853852
return
854853
end
855854

856-
local new_match_idx = self.current_match_idx + direction
855+
local new_match_idx = search_current_match_idx + direction
857856

858857
if new_match_idx > #new_matches then
859858
new_match_idx = 1
860859
elseif new_match_idx < 1 then
861860
new_match_idx = #new_matches
862861
end
863862

864-
self.matched_indices = new_matches
865-
self.current_match_idx = new_match_idx
863+
search_matched_indices = new_matches
864+
search_current_match_idx = new_match_idx
866865

867866
-- Scroll to the selected match
868-
local order_idx = self.matched_indices[self.current_match_idx]
867+
local order_idx = search_matched_indices[search_current_match_idx]
869868
mi.info.work_orders.scroll_position_work_orders = order_idx
870869
search_last_scroll_position = order_idx
871870
search_cursor_visible = true
@@ -875,21 +874,21 @@ function OrdersSearchOverlay:cycle_match(direction)
875874
end
876875

877876
function OrdersSearchOverlay:get_match_text()
878-
local total_matches = #self.matched_indices
877+
local total_matches = #search_matched_indices
879878

880879
if total_matches == 0 then
881880
return ''
882881
end
883882

884-
if self.current_match_idx == 0 then
883+
if search_current_match_idx == 0 then
885884
return string.format(': %d matches', total_matches)
886885
end
887886

888-
return string.format(': %d of %d', self.current_match_idx, total_matches)
887+
return string.format(': %d of %d', search_current_match_idx, total_matches)
889888
end
890889

891890
function OrdersSearchOverlay:has_matches()
892-
return #self.matched_indices > 0
891+
return #search_matched_indices > 0
893892
end
894893

895894
local function is_mouse_key(keys)
@@ -969,31 +968,43 @@ local function getViewportSize()
969968
return math.floor(available_height / ORDER_HEIGHT)
970969
end
971970

972-
local function calculateSelectedOrderY()
971+
local function getVisibleOrderIndices()
973972
local orders = df.global.world.manager_orders.all
974973
local scroll_pos = mi.info.work_orders.scroll_position_work_orders
975974

976-
if #orders == 0 or scroll_pos < 0 or scroll_pos >= #orders then
977-
return nil
978-
end
975+
if #orders == 0 then return 0, -1 end
979976

980-
local list_start_y = getListStartY()
981977
local viewport_size = getViewportSize()
982-
983978
local viewport_start = scroll_pos
984979
local viewport_end = scroll_pos + viewport_size - 1
985980

986-
-- Selected order tries to be at the top unless we're at the end of the list
981+
-- Handle end-of-list case
987982
if viewport_end >= #orders then
988983
viewport_end = #orders - 1
989984
viewport_start = math.max(0, viewport_end - viewport_size + 1)
990985
end
991986

992-
local pos_in_viewport = scroll_pos - viewport_start
987+
return viewport_start, viewport_end
988+
end
989+
990+
local function calculateOrderY(order_idx)
991+
local orders = df.global.world.manager_orders.all
992+
993+
if #orders == 0 or order_idx < 0 or order_idx >= #orders then
994+
return nil
995+
end
996+
997+
local viewport_start, viewport_end = getVisibleOrderIndices()
998+
999+
-- Check if order is in viewport
1000+
if order_idx < viewport_start or order_idx > viewport_end then
1001+
return nil
1002+
end
9931003

994-
local selected_y = list_start_y + (pos_in_viewport * ORDER_HEIGHT)
1004+
local list_start_y = getListStartY()
1005+
local pos_in_viewport = order_idx - viewport_start
9951006

996-
return selected_y
1007+
return list_start_y + (pos_in_viewport * ORDER_HEIGHT)
9971008
end
9981009

9991010
OrderHighlightOverlay = defclass(OrderHighlightOverlay, overlay.OverlayWidget)
@@ -1024,18 +1035,37 @@ function OrderHighlightOverlay:render(dc)
10241035
return
10251036
end
10261037

1027-
-- Draw highlight arrows
1028-
local selected_y = calculateSelectedOrderY()
1029-
if selected_y then
1030-
local highlight_pen = dfhack.pen.parse{
1031-
fg=COLOR_BLACK,
1032-
bg=COLOR_WHITE,
1033-
bold=true,
1034-
}
1035-
1036-
dc:seek(ARROW_X, selected_y):string('|', highlight_pen)
1037-
dc:seek(ARROW_X, selected_y + 1):string('>', highlight_pen)
1038-
dc:seek(ARROW_X, selected_y + 2):string('|', highlight_pen)
1038+
-- Draw highlight arrows for all matches in viewport
1039+
if #search_matched_indices == 0 then return end
1040+
1041+
local selected_pen = dfhack.pen.parse{
1042+
fg=COLOR_BLACK,
1043+
bg=COLOR_RED,
1044+
bold=true,
1045+
}
1046+
1047+
local match_pen = dfhack.pen.parse{
1048+
fg=COLOR_BLACK,
1049+
bg=COLOR_WHITE,
1050+
bold=true,
1051+
}
1052+
1053+
-- Get the order index of the currently selected match
1054+
local selected_order_idx = search_current_match_idx > 0 and
1055+
search_matched_indices[search_current_match_idx] or nil
1056+
1057+
-- Draw highlights for all matching orders in viewport
1058+
for _, match_order_idx in ipairs(search_matched_indices) do
1059+
local match_y = calculateOrderY(match_order_idx)
1060+
1061+
if match_y then
1062+
-- Use red pen for selected match, white for others
1063+
local pen = (match_order_idx == selected_order_idx) and selected_pen or match_pen
1064+
1065+
dc:seek(ARROW_X, match_y):string('|', pen)
1066+
dc:seek(ARROW_X, match_y + 1):string('>', pen)
1067+
dc:seek(ARROW_X, match_y + 2):string('|', pen)
1068+
end
10391069
end
10401070
end
10411071

0 commit comments

Comments
 (0)