-
Notifications
You must be signed in to change notification settings - Fork 198
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
search-filter.lua #846
search-filter.lua #846
Conversation
Searches dwarf citizens through a widget/window. Things to do is add ctrl + f to launch search-filter or alt + f. Well, any shortcut works as long as it's convenient.
hopefully fixed trailing white spaces
Cleared the whitespace Search for EOL in VScode settings and click on '\n' to make LF default
pre-commit.ci autofix |
for more information, see https://pre-commit.ci
I think I'm done. May be compatible with others.
I believe I'm done. I couldn't figure out how to add panels/tabs/buttons to the widget, but that's ok. I changed the conditions so visitors and hostile can be searched alongside citizens using the program.
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.
The comments in this code appear to violate rule 1 for code comment best practices: https://stackoverflow.blog/2021/12/23/best-practices-for-writing-code-comments/
that is, the comments are all either misleading or duplicate the code, which makes maintenance more difficult.
as far as I can tell, the code would be clearer if all comments were removed
at a higher level, though, given the complexity of getting this right, would it be perhaps better to implement it as search functionality for the vanilla units list? then you wouldn't have to depend on hacky workarounds for unit selection, and people would benefit from search without having to open a separate DFHack window. The data structures are in df.global.game.main_interface.info.cri_unit
local unitName = dfhack.TranslateName(dfhack.units.getVisibleName(unit)) | ||
if unitName == "" then | ||
-- Use the race name if the unit's name field is empty | ||
unitName = dfhack.units.getRaceName(unit) | ||
end |
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.
dfhack.units.getReadableName(unit)
would be a better fit here
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.
I added excessive comments because I'm not a programmer. These comments in the code are most likely wrong, and I'm open to having them all removed.
Regarding the program's functionality, it successfully realized my initial vision, which makes me satisfied. Additionally, I believe it's crucial to maintain the graphical user interface for the search filter program, as it offers an accessibility feature that I would greatly miss.
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.
Also I'm not interested in any recognition/credit so if someone is interested in taking all the code and calling it their own. I'm 100% happy with that. I just want others to enjoy the ability to ctrl+f aka use a search engine.
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.
Also feel free to contact me on discord: unboundlopez
widgets.EditField{ | ||
view_id='edit', | ||
frame={t=1, l=1}, -- Position of the EditField view | ||
text='', -- Initial text in the EditField view | ||
on_change=self:callback('updateList'), -- Callback function when text in EditField changes | ||
}, | ||
widgets.List{ | ||
view_id='list', | ||
frame={t=3, b=0}, | ||
choices=self:getFortControlledUnits(), -- Choices in the List view are obtained from getFortControlledUnits function | ||
on_select=self:callback('onSelect'), -- Callback function when a unit is selected from the list | ||
} |
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 should be a widgets.FilteredList
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.
Neat. Idk how to properly change it on the git hub or the code. I'm ok with the code being taken over by someone else.
unitName = dfhack.units.getRaceName(unit) | ||
end | ||
if dfhack.units.isVisible(unit) and dfhack.units.isActive(unit) then | ||
table.insert(fortControlledUnits, {text=unitName, search_normalized=dfhack.toSearchNormalized(unitName), id=unit.id}) |
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.
set search_key
instead of search_normalized
, and you don't need to normalize the key yourself with toSearchNormalized
. that is handled by widgets.FilteredList
function SearchEngine:updateList() | ||
local input = dfhack.toSearchNormalized(self.subviews.edit.text) | ||
local fortControlledUnits = self:getFortControlledUnits() | ||
local filtered_fortControlledUnits = {} | ||
|
||
for _, unit in ipairs(fortControlledUnits) do | ||
if string.find(unit.search_normalized, input) then | ||
table.insert(filtered_fortControlledUnits, unit) | ||
end | ||
end | ||
|
||
self.subviews.list:setChoices(filtered_fortControlledUnits) | ||
end |
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 can be removed once you move from widgets.List
to widgets.FilteredList
self.subviews.list:setChoices(filtered_fortControlledUnits) | ||
end | ||
|
||
function SearchEngine:onSelect(index, unit) |
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.
please fix the indentation for this function
-- Enable mouse tracking and set the left mouse button as pressed | ||
df.global.enabler.tracking_on = 1 | ||
df.global.enabler.mouse_lbut = 1 | ||
df.global.enabler.mouse_lbut_down = 1 |
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.
-- Enable mouse tracking and set the left mouse button as pressed | |
df.global.enabler.tracking_on = 1 | |
df.global.enabler.mouse_lbut = 1 | |
df.global.enabler.mouse_lbut_down = 1 |
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.
mouse button state is handled by gui.simulateInput()
df.global.enabler.mouse_lbut_down = 1 | ||
|
||
-- Simulate a left mouse click at the current mouse position | ||
gui.simulateInput(dfhack.gui.getDFViewscreen(), '_MOUSE_R') |
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.
why are you simulating a right click here?
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.
The reason I simulate a right click there is sometimes the program clicks on a object like a object or unit that doesn't want to get off the screen. Therefore, a right click somewhere in the screen closes out that pesky character sheet of the object that doesn't want to close.
-- Disable mouse tracking and set the left mouse button as not pressed | ||
df.global.enabler.tracking_on = 0 | ||
df.global.enabler.mouse_lbut = 0 | ||
df.global.enabler.mouse_lbut_down = 0 |
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.
-- Disable mouse tracking and set the left mouse button as not pressed | |
df.global.enabler.tracking_on = 0 | |
df.global.enabler.mouse_lbut = 0 | |
df.global.enabler.mouse_lbut_down = 0 |
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.
gui.simulateInput()
also handles mouse state restoration after sending input to the target screen
-- Screen creation | ||
SearchEngineScreen = defclass(SearchEngineScreen, gui.ZScreen) | ||
SearchEngineScreen.ATTRS = { | ||
focus_path='SearchEngine', |
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.
focus path should match the script name (search-filter
, or whatever we decide to rename this to)
-- Simulate a left mouse click at the current mouse position | ||
gui.simulateInput(dfhack.gui.getDFViewscreen(), '_MOUSE_R') | ||
|
||
gui.simulateInput(dfhack.gui.getDFViewscreen(), '_MOUSE_L') |
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.
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.
note that you can't just change df.global.game.main_interface.view_sheets.active_id
because that won't update the displayed text
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.
It is upsetting having the search filter bring up multiple units/objects when they are on top of each other. However, I personally don't mind clicking on the stacked pile of dwarf's/animals/monsters as I don't know how to bring up the searched name to the forefront when this occurs.
closing this as search functionality was integrated into the vanilla screens |
This code introduces a "Unit Search Engine" feature to Dwarf Fortress. It allows you to search for and select units within the game, simplifying the process of managing your fortress. I'm satisfied with the program's current functionality and have no plans to make further changes, the DFHack community master programmers can take over its maintenance and development. This feature can greatly enhance your Dwarf Fortress experience, making it easier to locate and interact with specific units in your fortress.
Dwarf.Fortress.2023.10.05-00.26.webm