diff --git a/src/app/script/dialog_class.cpp b/src/app/script/dialog_class.cpp index 7fa02674e..61b373c2c 100644 --- a/src/app/script/dialog_class.cpp +++ b/src/app/script/dialog_class.cpp @@ -107,6 +107,7 @@ struct Dialog { std::map dataWidgets; std::map labelWidgets; int currentRadioGroup = 0; + int autofit = ui::LEFT | ui::TOP; // Member used to hold current state about the creation of a tabs // widget. After creation it is reset to null to be ready for the @@ -193,6 +194,13 @@ struct Dialog { it->second->setText(text); } + void setAutofit(int align) + { + // Accept both 0 or a valid subset of align parameters. + if (align == 0 || (align & (ui::LEFT | ui::RIGHT | ui::TOP | ui::BOTTOM))) + autofit = align; + } + Display* parentDisplay() const { Display* parentDisplay = window.parentDisplay(); @@ -231,8 +239,10 @@ struct Dialog { window.display()->nativeWindow()->setFrame(frame); } else { + gfx::Rect oldBounds(window.bounds()); window.setBounds(rc); window.invalidate(); + parentDisplay()->invalidateRect(oldBounds); } } @@ -367,6 +377,7 @@ int Dialog_new(lua_State* L) ui::Window::Type windowType = ui::Window::WithTitleBar; std::string title = "Script"; bool sizeable = true; + int autofit = -1; if (lua_isstring(L, 1)) { title = lua_tostring(L, 1); } @@ -385,9 +396,16 @@ int Dialog_new(lua_State* L) if (type != LUA_TNIL && !lua_toboolean(L, -1)) sizeable = false; lua_pop(L, 1); + + type = lua_getfield(L, 1, "autofit"); + if (type != LUA_TNIL) { + autofit = lua_tointeger(L, -1); + } + lua_pop(L, 1); } auto dlg = push_new(L, windowType, title, sizeable); + dlg->setAutofit(autofit); // The uservalue of the dialog userdata will contain a table that // stores all the callbacks to handle events. As these callbacks can @@ -1654,8 +1672,26 @@ int Dialog_modify(lua_State* L) if (relayout && !dlg->window.isResizing()) { dlg->window.layout(); - gfx::Rect bounds(dlg->window.bounds().w, dlg->window.sizeHint().h); - dlg->window.expandWindow(bounds.size()); + if (dlg->autofit > 0) { + gfx::Rect oldBounds = dlg->window.bounds(); + gfx::Size resize(oldBounds.size()); + + if (dlg->autofit & ui::TOP || dlg->autofit & ui::BOTTOM) + resize.h = dlg->window.sizeHint().h; + if (dlg->autofit & ui::LEFT || dlg->autofit & ui::RIGHT) + resize.w = dlg->window.sizeHint().w; + + gfx::Size difference = resize - oldBounds.size(); + const auto& bounds = dlg->getWindowBounds(); + gfx::Rect newBounds(bounds.x, bounds.y, resize.w, resize.h); + + if (dlg->autofit & ui::BOTTOM) + newBounds.y = bounds.y - difference.h; + if (dlg->autofit & ui::RIGHT) + newBounds.x = bounds.x - difference.w; + + dlg->setWindowBounds(newBounds); + } } } lua_pushvalue(L, 1); @@ -1877,6 +1913,27 @@ int Dialog_get_bounds(lua_State* L) return 1; } +int Dialog_get_sizeHint(lua_State* L) +{ + auto dlg = get_obj(L, 1); + push_new(L, dlg->window.sizeHint()); + return 1; +} + +int Dialog_get_autofit(lua_State* L) +{ + auto dlg = get_obj(L, 1); + lua_pushinteger(L, dlg->autofit); + return 1; +} + +int Dialog_set_autofit(lua_State* L) +{ + auto dlg = get_obj(L, 1); + dlg->setAutofit(lua_tointeger(L, 2)); + return 0; +} + int Dialog_set_bounds(lua_State* L) { auto dlg = get_obj(L, 1); @@ -1918,9 +1975,11 @@ const luaL_Reg Dialog_methods[] = { }; const Property Dialog_properties[] = { - { "data", Dialog_get_data, Dialog_set_data }, - { "bounds", Dialog_get_bounds, Dialog_set_bounds }, - { nullptr, nullptr, nullptr } + { "data", Dialog_get_data, Dialog_set_data }, + { "bounds", Dialog_get_bounds, Dialog_set_bounds }, + { "autofit", Dialog_get_autofit, Dialog_set_autofit }, + { "sizeHint", Dialog_get_sizeHint, nullptr }, + { nullptr, nullptr, nullptr } }; } // anonymous namespace