implement box select from the UI

develop
Myk Taylor 2023-10-29 14:09:42 -07:00
parent cf1e4e69ca
commit f5f9f76ee1
No known key found for this signature in database
2 changed files with 63 additions and 21 deletions

@ -182,12 +182,41 @@ static void do_cycle(color_ostream &out)
// Lua API // Lua API
// //
static void get_opts(lua_State *L, int idx, bool &dry_run, bool &cur_zlevel) { static void get_bool_field(lua_State *L, int idx, const char *name, bool *dest) {
// TODO lua_getfield(L, idx, name);
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
return;
}
*dest = lua_toboolean(L, -1);
lua_pop(L, 1);
} }
static void get_bounds(lua_State *L, int idx, df::coord &pos1, df::coord &pos2) { static void get_opts(lua_State *L, int idx, bool &dry_run, bool &zlevel) {
// TODO if (lua_gettop(L) < idx)
return;
get_bool_field(L, idx, "dry_run", &dry_run);
get_bool_field(L, idx, "zlevel", &zlevel);
}
static bool get_int_field(lua_State *L, int idx, const char *name, int16_t *dest) {
lua_getfield(L, idx, name);
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
return false;
}
*dest = lua_tointeger(L, -1);
lua_pop(L, 1);
return true;
}
static bool get_bounds(lua_State *L, int idx, df::coord &pos1, df::coord &pos2) {
return get_int_field(L, idx, "x1", &pos1.x) &&
get_int_field(L, idx, "y1", &pos1.y) &&
get_int_field(L, idx, "z1", &pos1.z) &&
get_int_field(L, idx, "x2", &pos2.x) &&
get_int_field(L, idx, "y2", &pos2.y) &&
get_int_field(L, idx, "z2", &pos2.z);
} }
static int burrow_tiles_clear(lua_State *L) { static int burrow_tiles_clear(lua_State *L) {
@ -195,6 +224,7 @@ static int burrow_tiles_clear(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_tiles_clear\n"); DEBUG(status,*out).print("entering burrow_tiles_clear\n");
// TODO
return 0; return 0;
} }
@ -203,6 +233,7 @@ static int burrow_tiles_set(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_tiles_set\n"); DEBUG(status,*out).print("entering burrow_tiles_set\n");
// TODO
return 0; return 0;
} }
@ -211,6 +242,7 @@ static int burrow_tiles_add(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_tiles_add\n"); DEBUG(status,*out).print("entering burrow_tiles_add\n");
// TODO
return 0; return 0;
} }
@ -219,12 +251,13 @@ static int burrow_tiles_remove(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_tiles_remove\n"); DEBUG(status,*out).print("entering burrow_tiles_remove\n");
// TODO
return 0; return 0;
} }
static int box_fill(lua_State *L, bool enable) { static int box_fill(lua_State *L, bool enable) {
df::coord pos_start, pos_end; df::coord pos_start, pos_end;
bool dry_run = false, cur_zlevel = false; bool dry_run = false, zlevel = false;
df::burrow *burrow = NULL; df::burrow *burrow = NULL;
if (lua_isuserdata(L, 1)) if (lua_isuserdata(L, 1))
@ -239,10 +272,13 @@ static int box_fill(lua_State *L, bool enable) {
return 0; return 0;
} }
get_bounds(L, 2, pos_start, pos_end); if (!get_bounds(L, 2, pos_start, pos_end)) {
get_opts(L, 3, dry_run, cur_zlevel); luaL_argerror(L, 2, "invalid box bounds");
return 0;
}
get_opts(L, 3, dry_run, zlevel);
if (cur_zlevel) { if (zlevel) {
pos_start.z = *window_z; pos_start.z = *window_z;
pos_end.z = *window_z; pos_end.z = *window_z;
} }
@ -252,10 +288,10 @@ static int box_fill(lua_State *L, bool enable) {
for (int32_t y = pos_start.y; y <= pos_end.y; ++y) { for (int32_t y = pos_start.y; y <= pos_end.y; ++y) {
for (int32_t x = pos_start.x; x <= pos_end.x; ++x) { for (int32_t x = pos_start.x; x <= pos_end.x; ++x) {
df::coord pos(x, y, z); df::coord pos(x, y, z);
if (!Burrows::isAssignedTile(burrow, pos)) if (enable != Burrows::isAssignedTile(burrow, pos))
++count; ++count;
if (!dry_run) if (!dry_run)
Burrows::setAssignedTile(burrow, pos, true); Burrows::setAssignedTile(burrow, pos, enable);
} }
} }
} }
@ -285,6 +321,7 @@ static int burrow_tiles_flood_add(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_tiles_flood_add\n"); DEBUG(status,*out).print("entering burrow_tiles_flood_add\n");
// TODO
return 0; return 0;
} }
@ -293,6 +330,7 @@ static int burrow_tiles_flood_remove(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_tiles_flood_remove\n"); DEBUG(status,*out).print("entering burrow_tiles_flood_remove\n");
// TODO
return 0; return 0;
} }
@ -301,6 +339,7 @@ static int burrow_units_clear(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_units_clear\n"); DEBUG(status,*out).print("entering burrow_units_clear\n");
// TODO
return 0; return 0;
} }
@ -309,6 +348,7 @@ static int burrow_units_set(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_units_set\n"); DEBUG(status,*out).print("entering burrow_units_set\n");
// TODO
return 0; return 0;
} }
@ -317,6 +357,7 @@ static int burrow_units_add(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_units_add\n"); DEBUG(status,*out).print("entering burrow_units_add\n");
// TODO
return 0; return 0;
} }
@ -325,6 +366,7 @@ static int burrow_units_remove(lua_State *L) {
if (!out) if (!out)
out = &Core::getInstance().getConsole(); out = &Core::getInstance().getConsole();
DEBUG(status,*out).print("entering burrow_units_remove\n"); DEBUG(status,*out).print("entering burrow_units_remove\n");
// TODO
return 0; return 0;
} }

@ -87,14 +87,15 @@ function BurrowDesignationOverlay:init()
subviews={ subviews={
widgets.Label{ widgets.Label{
frame={t=0, l=1}, frame={t=0, l=1},
text='Double-click to fill.', text='Double-click to fill. Shift double-click to 3D fill.',
auto_width=true, auto_width=true,
visible=function() return not is_choosing_area() end,
}, },
widgets.Label{ widgets.Label{
frame={t=0, l=25}, frame={t=0, l=1},
text_pen=COLOR_DARKGREY, text_pen=COLOR_DARKGREY,
text={ text={
'Selected area: ', '3D box select enabled: ',
{text=function() return ('%dx%dx%d'):format(get_cur_area_dims()) end}, {text=function() return ('%dx%dx%d'):format(get_cur_area_dims()) end},
}, },
visible=is_choosing_area, visible=is_choosing_area,
@ -104,23 +105,22 @@ function BurrowDesignationOverlay:init()
} }
end end
local function flood_fill(pos, erasing, painting_burrow) local function flood_fill(pos, erasing, do_3d, painting_burrow)
local opts = {zlevel=not do_3d}
if erasing then if erasing then
burrow_tiles_flood_remove(painting_burrow, pos) burrow_tiles_flood_remove(painting_burrow, pos, opts)
else else
burrow_tiles_flood_add(painting_burrow, pos) burrow_tiles_flood_add(painting_burrow, pos, opts)
end end
reset_selection_rect() reset_selection_rect()
end end
local function box_fill(bounds, erasing, painting_burrow) local function box_fill(bounds, erasing, painting_burrow)
if bounds.z1 == bounds.z2 then return end if bounds.z1 == bounds.z2 then return end
local pos1 = xyz2pos(bounds.x1, bounds.y1, bounds.z1)
local pos2 = xyz2pos(bounds.x2, bounds.y2, bounds.z2)
if erasing then if erasing then
burrow_tiles_box_remove(painting_burrow, pos1, pos2) burrow_tiles_box_remove(painting_burrow, bounds)
else else
burrow_tiles_box_add(painting_burrow, pos1, pos2) burrow_tiles_box_add(painting_burrow, bounds)
end end
end end
@ -140,7 +140,7 @@ function BurrowDesignationOverlay:onInput(keys)
else else
if now_ms - self.last_click_ms <= widgets.DOUBLE_CLICK_MS then if now_ms - self.last_click_ms <= widgets.DOUBLE_CLICK_MS then
self.last_click_ms = 0 self.last_click_ms = 0
self.pending_fn = curry(flood_fill, pos, if_burrow.erasing) self.pending_fn = curry(flood_fill, pos, if_burrow.erasing, dfhack.internal.getModifiers().shift)
return return
else else
self.last_click_ms = now_ms self.last_click_ms = now_ms