|  |  |  | @ -2091,4 +2091,149 @@ function FilteredList:onFilterChar(char, text) | 
		
	
		
			
				|  |  |  |  |     return true | 
		
	
		
			
				|  |  |  |  | end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | local DEFAULT_ACTIVE_TAB_PENS = { | 
		
	
		
			
				|  |  |  |  |     text_mode_tab_pen=to_pen{fg=COLOR_YELLOW}, | 
		
	
		
			
				|  |  |  |  |     text_mode_label_pen=to_pen{fg=COLOR_WHITE}, | 
		
	
		
			
				|  |  |  |  |     lt=to_pen{tile=1005, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     lt2=to_pen{tile=1006, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     t=to_pen{tile=1007, fg=COLOR_BLACK, write_to_lower=true, top_of_text=true}, | 
		
	
		
			
				|  |  |  |  |     rt2=to_pen{tile=1008, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     rt=to_pen{tile=1009, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     lb=to_pen{tile=1015, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     lb2=to_pen{tile=1016, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     b=to_pen{tile=1017, fg=COLOR_BLACK, write_to_lower=true, bottom_of_text=true}, | 
		
	
		
			
				|  |  |  |  |     rb2=to_pen{tile=1018, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     rb=to_pen{tile=1019, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | local DEFAULT_INACTIVE_TAB_PENS = { | 
		
	
		
			
				|  |  |  |  |     text_mode_tab_pen=to_pen{fg=COLOR_BROWN}, | 
		
	
		
			
				|  |  |  |  |     text_mode_label_pen=to_pen{fg=COLOR_DARKGREY}, | 
		
	
		
			
				|  |  |  |  |     lt=to_pen{tile=1000, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     lt2=to_pen{tile=1001, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     t=to_pen{tile=1002, fg=COLOR_WHITE, write_to_lower=true, top_of_text=true}, | 
		
	
		
			
				|  |  |  |  |     rt2=to_pen{tile=1003, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     rt=to_pen{tile=1004, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     lb=to_pen{tile=1010, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     lb2=to_pen{tile=1011, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     b=to_pen{tile=1012, fg=COLOR_WHITE, write_to_lower=true, bottom_of_text=true}, | 
		
	
		
			
				|  |  |  |  |     rb2=to_pen{tile=1013, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  |     rb=to_pen{tile=1014, write_to_lower=true}, | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | --------- | 
		
	
		
			
				|  |  |  |  | -- Tab -- | 
		
	
		
			
				|  |  |  |  | --------- | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | Tab = defclass(Tabs, Widget) | 
		
	
		
			
				|  |  |  |  | Tab.ATTRS{ | 
		
	
		
			
				|  |  |  |  |     id=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  |     label=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  |     on_select=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  |     get_pens=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | function Tab:preinit(init_table) | 
		
	
		
			
				|  |  |  |  |     init_table.frame = init_table.frame or {} | 
		
	
		
			
				|  |  |  |  |     init_table.frame.w = #init_table.label + 4 | 
		
	
		
			
				|  |  |  |  |     init_table.frame.h = 2 | 
		
	
		
			
				|  |  |  |  | end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | function Tab:onRenderBody(dc) | 
		
	
		
			
				|  |  |  |  |     local pens = self.get_pens() | 
		
	
		
			
				|  |  |  |  |     dc:seek(0, 0) | 
		
	
		
			
				|  |  |  |  |     if dfhack.screen.inGraphicsMode() then | 
		
	
		
			
				|  |  |  |  |         dc:char(nil, pens.lt):char(nil, pens.lt2) | 
		
	
		
			
				|  |  |  |  |         for i=1,#self.label do | 
		
	
		
			
				|  |  |  |  |             dc:char(self.label:sub(i,i), pens.t) | 
		
	
		
			
				|  |  |  |  |         end | 
		
	
		
			
				|  |  |  |  |         dc:char(nil, pens.rt2):char(nil, pens.rt) | 
		
	
		
			
				|  |  |  |  |         dc:seek(0, 1) | 
		
	
		
			
				|  |  |  |  |         dc:char(nil, pens.lb):char(nil, pens.lb2) | 
		
	
		
			
				|  |  |  |  |         for i=1,#self.label do | 
		
	
		
			
				|  |  |  |  |             dc:char(self.label:sub(i,i), pens.b) | 
		
	
		
			
				|  |  |  |  |         end | 
		
	
		
			
				|  |  |  |  |         dc:char(nil, pens.rb2):char(nil, pens.rb) | 
		
	
		
			
				|  |  |  |  |     else | 
		
	
		
			
				|  |  |  |  |         local tp = pens.text_mode_tab_pen | 
		
	
		
			
				|  |  |  |  |         dc:char(' ', tp):char('/', tp) | 
		
	
		
			
				|  |  |  |  |         for i=1,#self.label do | 
		
	
		
			
				|  |  |  |  |             dc:char('-', tp) | 
		
	
		
			
				|  |  |  |  |         end | 
		
	
		
			
				|  |  |  |  |         dc:char('\\', tp):char(' ', tp) | 
		
	
		
			
				|  |  |  |  |         dc:seek(0, 1) | 
		
	
		
			
				|  |  |  |  |         dc:char('/', tp):char('-', tp) | 
		
	
		
			
				|  |  |  |  |         dc:string(self.label, pens.text_mode_label_pen) | 
		
	
		
			
				|  |  |  |  |         dc:char('-', tp):char('\\', tp) | 
		
	
		
			
				|  |  |  |  |     end | 
		
	
		
			
				|  |  |  |  | end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | function Tab:onInput(keys) | 
		
	
		
			
				|  |  |  |  |     if Tab.super.onInput(self, keys) then return true end | 
		
	
		
			
				|  |  |  |  |     if keys._MOUSE_L_DOWN and self:getMousePos() then | 
		
	
		
			
				|  |  |  |  |         self.on_select(self.id) | 
		
	
		
			
				|  |  |  |  |         return true | 
		
	
		
			
				|  |  |  |  |     end | 
		
	
		
			
				|  |  |  |  | end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | ------------- | 
		
	
		
			
				|  |  |  |  | -- Tab Bar -- | 
		
	
		
			
				|  |  |  |  | ------------- | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | TabBar = defclass(TabBar, ResizingPanel) | 
		
	
		
			
				|  |  |  |  | TabBar.ATTRS{ | 
		
	
		
			
				|  |  |  |  |     labels=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  |     on_select=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  |     get_cur_page=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  |     active_tab_pens=DEFAULT_ACTIVE_TAB_PENS, | 
		
	
		
			
				|  |  |  |  |     inactive_tab_pens=DEFAULT_INACTIVE_TAB_PENS, | 
		
	
		
			
				|  |  |  |  |     get_pens=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  |     switch_tab_key=DEFAULT_NIL, | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | function TabBar:init() | 
		
	
		
			
				|  |  |  |  |     for idx,label in ipairs(self.labels) do | 
		
	
		
			
				|  |  |  |  |         self:addviews{ | 
		
	
		
			
				|  |  |  |  |             Tab{ | 
		
	
		
			
				|  |  |  |  |                 frame={t=0, l=0}, | 
		
	
		
			
				|  |  |  |  |                 id=idx, | 
		
	
		
			
				|  |  |  |  |                 label=label, | 
		
	
		
			
				|  |  |  |  |                 on_select=self.on_select, | 
		
	
		
			
				|  |  |  |  |                 get_pens=self.get_pens and function() | 
		
	
		
			
				|  |  |  |  |                     return self.get_pens(idx, self) | 
		
	
		
			
				|  |  |  |  |                 end or function() | 
		
	
		
			
				|  |  |  |  |                     if self.get_cur_page() == idx then | 
		
	
		
			
				|  |  |  |  |                         return self.active_tab_pens | 
		
	
		
			
				|  |  |  |  |                     end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                     return self.inactive_tab_pens | 
		
	
		
			
				|  |  |  |  |                 end, | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     end | 
		
	
		
			
				|  |  |  |  | end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | function TabBar:postComputeFrame(body) | 
		
	
		
			
				|  |  |  |  |     local t, l, width = 0, 0, body.width | 
		
	
		
			
				|  |  |  |  |     for _,tab in ipairs(self.subviews) do | 
		
	
		
			
				|  |  |  |  |         if l > 0 and l + tab.frame.w > width then | 
		
	
		
			
				|  |  |  |  |             t = t + 2 | 
		
	
		
			
				|  |  |  |  |             l = 0 | 
		
	
		
			
				|  |  |  |  |         end | 
		
	
		
			
				|  |  |  |  |         tab.frame.t = t | 
		
	
		
			
				|  |  |  |  |         tab.frame.l = l | 
		
	
		
			
				|  |  |  |  |         l = l + tab.frame.w | 
		
	
		
			
				|  |  |  |  |     end | 
		
	
		
			
				|  |  |  |  | end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | function TabBar:onInput(keys) | 
		
	
		
			
				|  |  |  |  |     if TabBar.super.onInput(self, keys) then return true end | 
		
	
		
			
				|  |  |  |  |     if self.switch_tab_key and keys[self.switch_tab_key] then | 
		
	
		
			
				|  |  |  |  |         local zero_idx = self.get_cur_page() - 1 | 
		
	
		
			
				|  |  |  |  |         local next_zero_idx = (zero_idx + 1) % #self.labels | 
		
	
		
			
				|  |  |  |  |         self.on_select(next_zero_idx + 1) | 
		
	
		
			
				|  |  |  |  |         return true | 
		
	
		
			
				|  |  |  |  |     end | 
		
	
		
			
				|  |  |  |  | end | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | return _ENV | 
		
	
	
		
			
				
					|  |  |  | 
 |