Properly reverse BG/FG and apply per letter

This puts pen creation deeper into the loop in render_text.

Lists are current coloured completely wrong, though, and need
fixing (and probably anywhere else where disabled is set).
develop
Kelvie Wong 2023-02-16 21:38:27 -08:00
parent 0897ca913a
commit 3e8d0f0f1e
1 changed files with 42 additions and 50 deletions

@ -1080,7 +1080,26 @@ local function is_disabled(token)
(token.enabled ~= nil and not getval(token.enabled)) (token.enabled ~= nil and not getval(token.enabled))
end end
function render_text(obj,dc,x0,y0,pen,dpen,disabled) -- Make the hover pen -- that is a pen that should render elements that has the
-- mouse hovering over it. if hpen is specified, it just checks the fields and
-- returns it (in parsed pen form)
local function make_hpen(pen, hpen)
if not hpen then
pen = dfhack.pen.parse(pen)
-- Swap the foreground and background
hpen = dfhack.pen.make(pen.bg, nil, pen.fg + (pen.bold and 8 or 0))
end
-- text_hpen needs a character in order to paint the background using
-- Painter:fill(), so let's make it paint a space to show the background
-- color
local hpen_parsed = dfhack.pen.parse(hpen)
hpen_parsed.ch = string.byte(' ')
return hpen_parsed
end
function render_text(obj,dc,x0,y0,pen,dpen,disabled,hpen,hovered)
local width = 0 local width = 0
for iline = dc and obj.start_line_num or 1, #obj.text_lines do for iline = dc and obj.start_line_num or 1, #obj.text_lines do
local x, line = 0, obj.text_lines[iline] local x, line = 0, obj.text_lines[iline]
@ -1120,16 +1139,25 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled)
if dc then if dc then
local tpen = getval(token.pen) local tpen = getval(token.pen)
local dcpen = tpen or pen
-- If disabled, figure out which dpen to use
if disabled or is_disabled(token) then if disabled or is_disabled(token) then
dc:pen(getval(token.dpen) or tpen or dpen) dccpen = getval(token.dpen) or tpen or dpen
if keypen.fg ~= COLOR_BLACK then if keypen.fg ~= COLOR_BLACK then
keypen.bold = false keypen.bold = false
end end
else
dc:pen(tpen or pen) -- if hovered *and* disabled, combine both effects
if hovered then
dcpen = make_hpen(dcpen)
end end
elseif hovered then
dcpen = make_hpen(dcpen, getval(token.hpen) or hpen)
end end
dc:pen(dcpen)
end
local width = getval(token.width) local width = getval(token.width)
local padstr local padstr
if width then if width then
@ -1221,26 +1249,9 @@ function Label:init(args)
self:addviews{self.scrollbar} self:addviews{self.scrollbar}
-- use existing saved text if no explicit text was specified. this avoids
-- overwriting pre-formatted text that subclasses may have already set
self:setText(args.text or self.text) self:setText(args.text or self.text)
-- Inverts the brightness of the color -- self.text_hpen = make_hpen(self.text_pen, self.text_hpen)
local invert = function(color)
return (color + 8) % 16
end
-- default pen is an inverted foreground/background
if not self.text_hpen then
local text_pen = dfhack.pen.parse(self.text_pen)
self.text_hpen = dfhack.pen.make(invert(text_pen.fg), nil, invert(text_pen.bg))
end
-- text_hpen needs a character in order to paint the background using
-- Painter:fill(), so let's make it paint a space to show the background
-- color
local hpen_parsed = dfhack.pen.parse(self.text_hpen)
hpen_parsed.ch = string.byte(' ')
self.text_hpen = hpen_parsed
end end
local function update_label_scrollbar(label) local function update_label_scrollbar(label)
@ -1298,16 +1309,15 @@ function Label:onRenderFrame(dc, rect)
Label.super.onRenderFrame(self, dc, rect) Label.super.onRenderFrame(self, dc, rect)
-- Fill the background with text_hpen on hover -- Fill the background with text_hpen on hover
if self:getMousePos() and self:shouldHover() then if self:getMousePos() and self:shouldHover() then
dc:fill(rect, self.text_hpen) local hpen = make_hpen(self.text_pen, self.text_hpen)
dc:fill(rect, hpen)
end end
end end
function Label:onRenderBody(dc) function Label:onRenderBody(dc)
local text_pen = self.text_pen local text_pen = self.text_pen
if self:getMousePos() and self:shouldHover() then local hovered = self:getMousePos() and self:shouldHover()
text_pen = self.text_hpen render_text(self,dc,0,0,text_pen,self.text_dpen,is_disabled(self), self.text_hpen, hovered)
end
render_text(self,dc,0,0,text_pen,self.text_dpen,is_disabled(self))
end end
function Label:on_scrollbar(scroll_spec) function Label:on_scrollbar(scroll_spec)
@ -1635,22 +1645,7 @@ function List:init(info)
self.last_select_click_ms = 0 -- used to track double-clicking on an item self.last_select_click_ms = 0 -- used to track double-clicking on an item
-- Inverts the brightness of the color -- self.text_hpen = make_hpen(self.text_pen, self.text_hpen)
invert = function(color)
return (color + 8) % 16
end
-- default pen is an inverted foreground/background
if not self.text_hpen then
local text_pen = dfhack.pen.parse(self.text_pen)
self.text_hpen = dfhack.pen.make(invert(text_pen.fg), nil, invert(text_pen.bg))
end
-- text_hpen needs a character in order to paint the background using
-- Painter:fill(), so let's make it paint a space to show the background
-- color
local hpen_parsed = dfhack.pen.parse(self.text_hpen)
hpen_parsed.ch = string.byte(' ')
self.text_hpen = hpen_parsed
end end
function List:setChoices(choices, selected) function List:setChoices(choices, selected)
@ -1807,15 +1802,12 @@ function List:onRenderBody(dc)
local obj = choices[i] local obj = choices[i]
local current = (i == self.selected) local current = (i == self.selected)
local hovered = (i == hoveridx) local hovered = (i == hoveridx)
-- cur_pen and cur_dpen can't be integers or background colors get
-- messed up in render_text for subsequent renders
local cur_pen = to_pen(self.cursor_pen) local cur_pen = to_pen(self.cursor_pen)
local cur_dpen = to_pen(self.text_pen) local cur_dpen = to_pen(self.text_pen)
local active_pen = (current and cur_pen or cur_dpen) local active_pen = (current and cur_pen or cur_dpen)
-- when mouse is over, always highlight it
if hovered then
cur_dpen = self.text_hpen
end
if not getval(self.active) then if not getval(self.active) then
cur_pen = self.inactive_pen or self.cursor_pen cur_pen = self.inactive_pen or self.cursor_pen
end end
@ -1828,7 +1820,7 @@ function List:onRenderBody(dc)
paint_icon(icon, obj) paint_icon(icon, obj)
end end
render_text(obj, dc, iw or 0, y, cur_pen, cur_dpen, not current) render_text(obj, dc, iw or 0, y, cur_pen, cur_dpen, not current, self.text_hpen, hovered)
local ip = dc.width local ip = dc.width