support foreground and background writing from pens

develop
Myk Taylor 2023-01-11 18:23:16 -08:00
parent 3ed65aedbf
commit 079d5e4178
No known key found for this signature in database
7 changed files with 50 additions and 9 deletions

@ -49,6 +49,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## API
- ``Gui::getDwarfmodeDims``: now only returns map viewport dimensions; menu dimensions are obsolete
- ``Gui::getDFViewscreen``: returns the topmost underlying DF viewscreen
- ``Screen::Pen``: now accepts ``keep_lower`` and ``write_to_lower`` properties to support foreground and background textures in graphics mode
## Lua
- Removed ``os.execute()`` and ``io.popen()`` built-in functions
@ -58,10 +59,13 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- ``widgets.CycleHotkeyLabel``: now supports rendering option labels in the color of your choice
- ``widgets.CycleHotkeyLabel``: new functions ``setOption()`` and ``getOptionPen()``
- ``widgets.ToggleHotkeyLabel``: now renders the ``On`` option in green text
- ``widgets.Label``: tiles can now have an associated width
- `overlay`: ``OverlayWidget`` now inherits from ``Panel`` instead of ``Widget`` to get all the frame and mouse integration goodies
- ``dfhack.gui.getDFViewscreen()``: returns the topmost underlying DF viewscreen
- ``gui.ZScreen``: Screen subclass that implements window raising, multi-viewscreen input handling, and viewscreen event pass-through so the underlying map can be interacted with and dragged around while DFHack screens are visible
- ``gui.View``: new function ``view:getMouseFramePos()`` for detecting whether the mouse is within (or over) the exterior frame of a view
- ``gui.CLEAR_PEN``: now clears the background and foreground and writes to the background (before it would always write to the foreground)
- ``gui.KEEP_LOWER_PEN``: a general use pen that writes associated tiles to the foreground while keeping the existing background
## Internals

@ -2266,6 +2266,12 @@ a table with the following possible fields:
Specifies that the tile should be shaded with *fg/bg*.
``tile_fg, tile_bg``
If specified, overrides *tile_color* and supplies shading colors directly.
``keep_lower``
If set to true, will not overwrite the background tile when filling in
the foreground tile.
``write_to_lower``
If set to true, the specified ``tile`` will be written to the background
instead of the foreground.
Alternatively, it may be a pre-parsed native object with the following API:
@ -3654,7 +3660,13 @@ Misc
* ``CLEAR_PEN``
The black pen used to clear the screen.
The black pen used to clear the screen. In graphics mode, it will clear the
foreground and set the background to the standard black tile.
* ``KEEP_LOWER_PEN``
A pen that will write tiles over existing background tiles instead of clearing
them.
* ``simulateInput(screen, keys...)``
@ -4582,8 +4594,8 @@ containing newlines, or a table with the following possible fields:
* ``token.width = ...``
If specified either as a value or a callback, the text field is padded
or truncated to the specified number.
If specified either as a value or a callback, the text (or tile) field is
padded or truncated to the specified number.
* ``token.pad_char = '?'``

@ -177,6 +177,17 @@ static bool get_char_field(lua_State *L, char *pf, int idx, const char *name, ch
}
}
static bool get_bool_field(lua_State *L, bool *pf, int idx, const char *name, bool defval) {
lua_getfield(L, idx, name);
bool nil = lua_isnil(L, -1);
if (nil)
*pf = defval;
else
*pf = lua_toboolean(L, -1);
lua_pop(L, 1);
return !nil;
}
static void decode_pen(lua_State *L, Pen &pen, int idx)
{
idx = lua_absindex(L, idx);
@ -208,6 +219,9 @@ static void decode_pen(lua_State *L, Pen &pen, int idx)
pen.tile_mode = (lua_toboolean(L, -1) ? Pen::CharColor : Pen::AsIs);
lua_pop(L, 1);
}
get_bool_field(L, &pen.keep_lower, idx, "keep_lower", false);
get_bool_field(L, &pen.write_to_lower, idx, "write_to_lower", false);
}
/**************************************************

@ -84,6 +84,9 @@ namespace DFHack
} tile_mode;
int8_t tile_fg, tile_bg;
bool write_to_lower = false;
bool keep_lower = false;
bool valid() const { return tile >= 0; }
bool empty() const { return ch == 0 && tile == 0; }

@ -9,7 +9,8 @@ local getval = utils.getval
local to_pen = dfhack.pen.parse
CLEAR_PEN = to_pen{tile=909, ch=32, fg=0, bg=0}
CLEAR_PEN = to_pen{tile=909, ch=32, fg=0, bg=0, write_to_lower=true}
KEEP_LOWER_PEN = to_pen{ch=32, fg=0, bg=0, keep_lower=true}
local FAKE_INPUT_KEYS = {
_MOUSE_L = true,

@ -688,7 +688,6 @@ function EditField:onRenderBody(dc)
end_pos == #txt and '' or string.char(26))
end
dc:advance(self.text_offset):string(txt)
dc:string((' '):rep(dc.clip_x2 - dc.x))
end
function EditField:insert(text)
@ -1102,6 +1101,9 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled)
x = x + 1
if dc then
dc:tile(nil, token.tile)
if token.width then
dc:advance(token.width-1)
end
end
end

@ -157,7 +157,8 @@ static bool doSetTile_default(const Pen &pen, int x, int y, bool map)
*screen = 0;
*texpos = 0;
*texpos_lower = 0;
if (!pen.keep_lower)
*texpos_lower = 0;
gps->screentexpos_anchored[index] = 0;
// keep SCREENTEXPOS_FLAG_ANCHOR_SUBORDINATE so occluded anchored textures
// don't appear corrupted
@ -171,7 +172,8 @@ static bool doSetTile_default(const Pen &pen, int x, int y, bool map)
*screen = 0;
*texpos = 0;
*texpos_lower = 0;
if (!pen.keep_lower)
*texpos_lower = 0;
gps->screentexpos_top_anchored[index] = 0;
*flag &= 4; // keep SCREENTEXPOS_FLAG_ANCHOR_SUBORDINATE
}
@ -190,10 +192,13 @@ static bool doSetTile_default(const Pen &pen, int x, int y, bool map)
}
if (pen.tile && use_graphics) {
*texpos = pen.tile;
if (pen.write_to_lower)
*texpos_lower = pen.tile;
else
*texpos = pen.tile;
} else {
screen[0] = uint8_t(pen.ch);
*texpos_lower = 909;
*texpos_lower = 909; // basic black background
}
auto rgb_fg = &gps->uccolor[fg][0];