add basic framework for info search widget
parent
37ad0c3e6f
commit
ae1d6f98f6
@ -0,0 +1,139 @@
|
||||
local _ENV = mkmodule('plugins.sort.creatures')
|
||||
|
||||
local overlay = require('plugins.overlay')
|
||||
local widgets = require('gui.widgets')
|
||||
|
||||
local creatures = df.global.game.main_interface.info.creatures
|
||||
|
||||
-- ----------------------
|
||||
-- InfoOverlay
|
||||
--
|
||||
|
||||
InfoOverlay = defclass(InfoOverlay, overlay.OverlayWidget)
|
||||
InfoOverlay.ATTRS{
|
||||
default_pos={x=64, y=9},
|
||||
default_enabled=true,
|
||||
viewscreens={
|
||||
'dwarfmode/Info/CREATURES/CITIZEN',
|
||||
'dwarfmode/Info/CREATURES/PET',
|
||||
'dwarfmode/Info/CREATURES/OverallTraining',
|
||||
'dwarfmode/Info/CREATURES/AddingTrainer',
|
||||
'dwarfmode/Info/CREATURES/OTHER',
|
||||
'dwarfmode/Info/CREATURES/DECEASED',
|
||||
},
|
||||
hotspot=true,
|
||||
overlay_onupdate_max_freq_seconds=0,
|
||||
frame={w=40, h=3},
|
||||
}
|
||||
|
||||
function InfoOverlay:init()
|
||||
self.state = {}
|
||||
|
||||
self:addviews{
|
||||
widgets.BannerPanel{
|
||||
view_id='panel',
|
||||
frame={l=0, t=0, r=0, h=1},
|
||||
subviews={
|
||||
widgets.EditField{
|
||||
view_id='search',
|
||||
frame={l=1, t=0, r=1},
|
||||
label_text="Search: ",
|
||||
key='CUSTOM_ALT_S',
|
||||
on_change=self:callback('text_input'),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function InfoOverlay:overlay_onupdate(scr)
|
||||
if next(self.state) and not dfhack.gui.matchFocusString('dwarfmode/Info', scr) then
|
||||
-- TODO: add dynamically allocated elements that were not visible at the time of
|
||||
-- closure back to the list so they can be properly disposed of
|
||||
self.state = {}
|
||||
self.subviews.search:setText('')
|
||||
self.subviews.search:setFocus(false)
|
||||
self.overlay_onupdate_max_freq_seconds = 60
|
||||
end
|
||||
end
|
||||
|
||||
local function are_tabs_in_two_rows()
|
||||
local pen = dfhack.screen.readTile(64, 6, false) -- tile is occupied iff tabs are in one row
|
||||
return pen.ch == 0
|
||||
end
|
||||
|
||||
local function resize_overlay(self)
|
||||
local sw = dfhack.screen.getWindowSize()
|
||||
local overlay_width = math.min(40, sw-(self.frame_rect.x1 + 30))
|
||||
if overlay_width ~= self.frame.w then
|
||||
self.frame.w = overlay_width
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function InfoOverlay:updateFrames()
|
||||
local ret = resize_overlay(self)
|
||||
local two_rows = are_tabs_in_two_rows()
|
||||
if (self.two_rows == two_rows) then return ret end
|
||||
self.two_rows = two_rows
|
||||
self.subviews.panel.frame.t = two_rows and 2 or 0
|
||||
return true
|
||||
end
|
||||
|
||||
local function get_key()
|
||||
if creatures.current_mode == df.unit_list_mode_type.PET then
|
||||
if creatures.showing_overall_training then
|
||||
return 'PET_OT'
|
||||
elseif creatures.adding_trainer then
|
||||
return 'PET_AT'
|
||||
end
|
||||
end
|
||||
return df.unit_list_mode_type[creatures.current_mode]
|
||||
end
|
||||
|
||||
local function check_context(self)
|
||||
local key = get_key()
|
||||
if self.state.prev_key ~= key then
|
||||
self.state.prev_key = key
|
||||
local prev_text = ensure_key(self.state, key).prev_text
|
||||
self.subviews.search:setText(prev_text or '')
|
||||
end
|
||||
end
|
||||
|
||||
function InfoOverlay:onRenderBody(dc)
|
||||
if next(self.state) then
|
||||
check_context(self)
|
||||
end
|
||||
if self:updateFrames() then
|
||||
self:updateLayout()
|
||||
end
|
||||
self.overlay_onupdate_max_freq_seconds = 0
|
||||
InfoOverlay.super.onRenderBody(self, dc)
|
||||
end
|
||||
|
||||
function InfoOverlay:text_input(text)
|
||||
if not next(self.state) and text == '' then return end
|
||||
-- the EditField state is guaranteed to be consistent with the current
|
||||
-- context since when clicking to switch tabs, onRenderBody is always called
|
||||
-- before this text_input callback, even if a key is pressed before the next
|
||||
-- graphical frame would otherwise be printed. if this ever becomes untrue,
|
||||
-- then we can add an on_char handler to the EditField that also calls
|
||||
-- check_context.
|
||||
local key = get_key()
|
||||
local prev_text = ensure_key(self.state, key).prev_text
|
||||
if text == prev_text then return end
|
||||
if prev_text and text:startswith(prev_text) then
|
||||
-- TODO: search
|
||||
print('performing incremental search; text:', text, 'key:', key)
|
||||
else
|
||||
-- TODO: save list if not already saved
|
||||
-- TODO: else restore list from saved list
|
||||
-- TODO: if text ~= '' then search
|
||||
-- TODO: sort according to vanilla sort widget state
|
||||
print('performing full search; text:', text, 'key:', key)
|
||||
end
|
||||
-- TODO: save visible list
|
||||
self.state[key].prev_text = text
|
||||
end
|
||||
|
||||
return _ENV
|
Loading…
Reference in New Issue