mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 10:31:50 +00:00
Share settings page helpers, add GUI cursor/scale API
- move create_trackbar_setting/update_trackbar_label/create_checkbox from settings_audio/display/graphics pages to core:settings_common module - GUI scale trackbar shows the really applied scale, e.g. '3 (effective 2)' - add gui.get_scale(), gui.get_max_scale(), gui.get_cursor_pos() (UI units); document that input.get_mouse_pos() returns window pixels - InventoryView default color is defined once (InventoryView::DEFAULT_COLOR) instead of duplicated literals; 'color' attribute still overrides it
This commit is contained in:
parent
851c1a0e27
commit
33e132a231
15 changed files with 173 additions and 123 deletions
|
|
@ -16,6 +16,17 @@ gui.str(text: str, context: str) -> str
|
|||
-- Returns size of the main container (window).
|
||||
gui.get_viewport() -> {int, int}
|
||||
|
||||
-- Returns current GUI scale: window pixels per one UI unit (1..4).
|
||||
-- Set by the display.gui-scale setting and limited by window size.
|
||||
gui.get_scale() -> int
|
||||
|
||||
-- Returns maximal GUI scale that fits the current window size.
|
||||
gui.get_max_scale() -> int
|
||||
|
||||
-- Returns cursor position in UI units (unlike input.get_mouse_pos,
|
||||
-- which returns window pixels). Use it to position UI elements.
|
||||
gui.get_cursor_pos() -> {number, number}
|
||||
|
||||
-- Returns environment (global variables table) of the specified document.
|
||||
gui.get_env(document: str) -> table
|
||||
```
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ end, document.root)
|
|||
input.get_mouse_pos() --> {int, int}
|
||||
```
|
||||
|
||||
Returns cursor screen position.
|
||||
Returns cursor screen position in window pixels.
|
||||
To get position in UI units (affected by GUI scale) use `gui.get_cursor_pos()`.
|
||||
|
||||
```lua
|
||||
input.get_mouse_delta() --> {int, int}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,17 @@ gui.str(text: string, context: string) -> string
|
|||
-- Возвращает размер главного контейнера (окна).
|
||||
gui.get_viewport() -> {number, number}
|
||||
|
||||
-- Возвращает текущий масштаб интерфейса: пикселей окна в одной единице UI (1..4).
|
||||
-- Задаётся настройкой display.gui-scale и ограничивается размером окна.
|
||||
gui.get_scale() -> int
|
||||
|
||||
-- Возвращает максимальный масштаб интерфейса, помещающийся в текущее окно.
|
||||
gui.get_max_scale() -> int
|
||||
|
||||
-- Возвращает позицию курсора в единицах UI (в отличие от input.get_mouse_pos,
|
||||
-- возвращающей пиксели окна). Используйте для позиционирования элементов UI.
|
||||
gui.get_cursor_pos() -> {number, number}
|
||||
|
||||
-- Возвращает окружение (глобальные переменные) указанного документа.
|
||||
gui.get_env(document: string) -> table
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ input.set_enabled(bindname: string, flag: boolean)
|
|||
|
||||
## Курсор мыши
|
||||
```lua
|
||||
-- Возвращает позицию курсора на экране.
|
||||
-- Возвращает позицию курсора на экране в пикселях окна.
|
||||
-- Для позиции в единицах UI (с учётом масштаба) используйте gui.get_cursor_pos().
|
||||
input.get_mouse_pos() -> {number, number}
|
||||
|
||||
-- Возращает дельту позиции курсора.
|
||||
|
|
|
|||
|
|
@ -1,30 +1,7 @@
|
|||
function create_trackbar_setting(id, name, step, postfix, tooltip)
|
||||
local info = app.get_setting_info(id)
|
||||
postfix = postfix or ""
|
||||
tooltip = tooltip or ""
|
||||
document.root:add(gui.template("track_setting", {
|
||||
id=id,
|
||||
name=gui.str(name, "settings"),
|
||||
value=app.get_setting(id),
|
||||
min=info.min,
|
||||
max=info.max,
|
||||
step=step,
|
||||
postfix=postfix,
|
||||
tooltip=gui.str(tooltip, "settings")
|
||||
}))
|
||||
update_trackbar_label(app.get_setting(id), id, name, postfix)
|
||||
end
|
||||
|
||||
function update_trackbar_label(x, id, name, postfix)
|
||||
app.set_setting(id, x)
|
||||
-- updating label
|
||||
document[id..".L"].text = string.format(
|
||||
"%s: %s%s",
|
||||
gui.str(name, "settings"),
|
||||
app.str_setting(id),
|
||||
postfix
|
||||
)
|
||||
end
|
||||
local settings = require "core:settings_common".new(document, {})
|
||||
-- templates call these functions by name, so they must be global
|
||||
create_trackbar_setting = settings.create_trackbar_setting
|
||||
update_trackbar_label = settings.update_trackbar_label
|
||||
|
||||
function update_checkbox_setting(id, value)
|
||||
app.set_setting(id, value)
|
||||
|
|
@ -43,12 +20,8 @@ function update_checkbox_setting(id, value)
|
|||
end
|
||||
end
|
||||
|
||||
function create_checkbox(id, name, tooltip)
|
||||
tooltip = tooltip or ''
|
||||
document.root:add(string.format(
|
||||
"<checkbox consumer='function(x) update_checkbox_setting(\"%s\", x) end' checked='%s' tooltip='%s'>%s</checkbox>",
|
||||
id, app.str_setting(id), gui.str(tooltip, "settings"), gui.str(name, "settings")
|
||||
))
|
||||
local function create_audio_checkbox(id, name, tooltip)
|
||||
settings.create_checkbox(id, name, tooltip, "update_checkbox_setting")
|
||||
update_checkbox_setting(id, app.get_setting(id))
|
||||
end
|
||||
|
||||
|
|
@ -103,6 +76,6 @@ function on_open()
|
|||
selectbox.value = app.get_setting("audio.input-device")
|
||||
end
|
||||
|
||||
create_checkbox("audio.recording-enabled", "Microphone access", "audio.recording-enabled.tooltip")
|
||||
create_checkbox("audio.acoustic-effects", "Acoustic effects", "audio.acoustic-effects.tooltip")
|
||||
create_audio_checkbox("audio.recording-enabled", "Microphone access", "audio.recording-enabled.tooltip")
|
||||
create_audio_checkbox("audio.acoustic-effects", "Acoustic effects", "audio.acoustic-effects.tooltip")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,57 +10,24 @@ tostring_overrides["display.framerate"] = function(x)
|
|||
end
|
||||
|
||||
tostring_overrides["display.gui-scale"] = function(x)
|
||||
-- scale is limited by the window size, show what is really applied
|
||||
local effective = gui.get_max_scale()
|
||||
if x > 0 then
|
||||
effective = math.min(x, effective)
|
||||
end
|
||||
if x == 0 then
|
||||
return gui.str("Auto")
|
||||
else
|
||||
return tostring(x)
|
||||
return string.format("%s (%d)", gui.str("Auto"), effective)
|
||||
elseif effective < x then
|
||||
return string.format("%d (%s %d)", x, gui.str("Effective"), effective)
|
||||
end
|
||||
return tostring(x)
|
||||
end
|
||||
|
||||
function create_trackbar_setting(id, name, step, postfix, tooltip, changeonrelease)
|
||||
local info = app.get_setting_info(id)
|
||||
postfix = postfix or ""
|
||||
tooltip = tooltip or ""
|
||||
changeonrelease = changeonrelease or ""
|
||||
document.root:add(gui.template("track_setting", {
|
||||
id=id,
|
||||
name=gui.str(name, "settings"),
|
||||
value=app.get_setting(id),
|
||||
min=info.min,
|
||||
max=info.max,
|
||||
step=step,
|
||||
postfix=postfix,
|
||||
tooltip=tooltip,
|
||||
changeonrelease=changeonrelease
|
||||
}))
|
||||
update_trackbar_label(app.get_setting(id), id, name, postfix)
|
||||
end
|
||||
|
||||
function update_trackbar_label(x, id, name, postfix)
|
||||
local str
|
||||
local func = tostring_overrides[id]
|
||||
if func then
|
||||
str = func(x)
|
||||
else
|
||||
str = app.str_setting(id)
|
||||
end
|
||||
-- updating label
|
||||
document[id..".L"].text = string.format(
|
||||
"%s: %s%s",
|
||||
gui.str(name, "settings"),
|
||||
str,
|
||||
postfix
|
||||
)
|
||||
end
|
||||
|
||||
function create_checkbox(id, name, tooltip)
|
||||
tooltip = tooltip or ''
|
||||
document.root:add(string.format(
|
||||
"<checkbox consumer='function(x) app.set_setting(\"%s\", x) end' checked='%s' tooltip='%s'>%s</checkbox>",
|
||||
id, app.str_setting(id), gui.str(tooltip, "settings"), gui.str(name, "settings")
|
||||
))
|
||||
end
|
||||
|
||||
local settings = require "core:settings_common".new(document, {tostring_overrides=tostring_overrides})
|
||||
-- templates call these functions by name, so they must be global
|
||||
create_trackbar_setting = settings.create_trackbar_setting
|
||||
update_trackbar_label = settings.update_trackbar_label
|
||||
create_checkbox = settings.create_checkbox
|
||||
|
||||
function on_open()
|
||||
create_trackbar_setting("camera.fov", "FOV", 1, "°")
|
||||
|
|
|
|||
|
|
@ -1,39 +1,8 @@
|
|||
function create_trackbar_setting(id, name, step, postfix, tooltip, changeonrelease)
|
||||
local info = app.get_setting_info(id)
|
||||
postfix = postfix or ""
|
||||
tooltip = tooltip or ""
|
||||
changeonrelease = changeonrelease or ""
|
||||
document.root:add(gui.template("track_setting", {
|
||||
id=id,
|
||||
name=gui.str(name, "settings"),
|
||||
value=app.get_setting(id),
|
||||
min=info.min,
|
||||
max=info.max,
|
||||
step=step,
|
||||
postfix=postfix,
|
||||
tooltip=tooltip,
|
||||
changeonrelease=changeonrelease
|
||||
}))
|
||||
update_trackbar_label(app.get_setting(id), id, name, postfix)
|
||||
end
|
||||
|
||||
function update_trackbar_label(x, id, name, postfix)
|
||||
-- updating label
|
||||
document[id..".L"].text = string.format(
|
||||
"%s: %s%s",
|
||||
gui.str(name, "settings"),
|
||||
app.str_setting(id),
|
||||
postfix
|
||||
)
|
||||
end
|
||||
|
||||
function create_checkbox(id, name, tooltip)
|
||||
tooltip = tooltip or ''
|
||||
document.root:add(string.format(
|
||||
"<checkbox consumer='function(x) app.set_setting(\"%s\", x) end' checked='%s' tooltip='%s'>%s</checkbox>",
|
||||
id, app.str_setting(id), gui.str(tooltip, "settings"), gui.str(name, "settings")
|
||||
))
|
||||
end
|
||||
local settings = require "core:settings_common".new(document, {})
|
||||
-- templates call these functions by name, so they must be global
|
||||
create_trackbar_setting = settings.create_trackbar_setting
|
||||
update_trackbar_label = settings.update_trackbar_label
|
||||
create_checkbox = settings.create_checkbox
|
||||
|
||||
function on_open()
|
||||
create_trackbar_setting("chunks.load-distance", "Load Distance", 1)
|
||||
|
|
|
|||
84
res/modules/settings_common.lua
Normal file
84
res/modules/settings_common.lua
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
-- Common helpers for settings pages (res/layouts/pages/settings_*.xml.lua).
|
||||
--
|
||||
-- Usage in a page script:
|
||||
--
|
||||
-- local settings = require "core:settings_common".new(document, {
|
||||
-- tostring_overrides = {["display.framerate"] = function(x) ... end}
|
||||
-- })
|
||||
-- -- templates call these functions by name, so they must be global
|
||||
-- create_trackbar_setting = settings.create_trackbar_setting
|
||||
-- update_trackbar_label = settings.update_trackbar_label
|
||||
-- create_checkbox = settings.create_checkbox
|
||||
|
||||
local settings_common = {}
|
||||
|
||||
--- Create helpers bound to the page document.
|
||||
--- @param document the page document
|
||||
--- @param options table (optional) with fields:
|
||||
--- tostring_overrides: {[setting_id] = function(value) -> string}
|
||||
function settings_common.new(document, options)
|
||||
options = options or {}
|
||||
local tostring_overrides = options.tostring_overrides or {}
|
||||
local this = {}
|
||||
|
||||
--- Update trackbar label (called by the track_setting template)
|
||||
function this.update_trackbar_label(x, id, name, postfix)
|
||||
local str
|
||||
local func = tostring_overrides[id]
|
||||
if func then
|
||||
str = func(x)
|
||||
else
|
||||
str = app.str_setting(id)
|
||||
end
|
||||
document[id..".L"].text = string.format(
|
||||
"%s: %s%s",
|
||||
gui.str(name, "settings"),
|
||||
str,
|
||||
postfix
|
||||
)
|
||||
end
|
||||
|
||||
--- Add a trackbar bound to the setting
|
||||
--- @param changeonrelease apply value only when mouse is released
|
||||
function this.create_trackbar_setting(
|
||||
id, name, step, postfix, tooltip, changeonrelease
|
||||
)
|
||||
local info = app.get_setting_info(id)
|
||||
postfix = postfix or ""
|
||||
tooltip = tooltip or ""
|
||||
changeonrelease = changeonrelease or ""
|
||||
document.root:add(gui.template("track_setting", {
|
||||
id=id,
|
||||
name=gui.str(name, "settings"),
|
||||
value=app.get_setting(id),
|
||||
min=info.min,
|
||||
max=info.max,
|
||||
step=step,
|
||||
postfix=postfix,
|
||||
tooltip=tooltip,
|
||||
changeonrelease=changeonrelease
|
||||
}))
|
||||
this.update_trackbar_label(app.get_setting(id), id, name, postfix)
|
||||
end
|
||||
|
||||
--- Add a checkbox bound to the setting
|
||||
--- @param consumer name of a global page function(id, value) called on
|
||||
--- change instead of just setting the value (optional)
|
||||
function this.create_checkbox(id, name, tooltip, consumer)
|
||||
tooltip = tooltip or ""
|
||||
local action
|
||||
if consumer then
|
||||
action = string.format("%s(\"%s\", x)", consumer, id)
|
||||
else
|
||||
action = string.format("app.set_setting(\"%s\", x)", id)
|
||||
end
|
||||
document.root:add(string.format(
|
||||
"<checkbox consumer='function(x) %s end' checked='%s' tooltip='%s'>%s</checkbox>",
|
||||
action, app.str_setting(id), gui.str(tooltip, "settings"), gui.str(name, "settings")
|
||||
))
|
||||
end
|
||||
|
||||
return this
|
||||
end
|
||||
|
||||
return settings_common
|
||||
|
|
@ -13,6 +13,7 @@ Description=Описание
|
|||
Converting world...=Выполняется конвертация мира...
|
||||
Unlimited=Неограниченно
|
||||
Auto=Авто
|
||||
Effective=действует
|
||||
Chat=Чат
|
||||
Console=Консоль
|
||||
Log=Лог
|
||||
|
|
|
|||
|
|
@ -93,13 +93,18 @@ void GUI::onAssetsLoad(Assets* assets) {
|
|||
static constexpr glm::uvec2 MIN_UI_SIZE {640, 480};
|
||||
static constexpr int MAX_SCALE = 4;
|
||||
|
||||
int GUI::calcScale(const glm::uvec2& viewport) const {
|
||||
int GUI::calcMaxScale(const glm::uvec2& viewport) {
|
||||
int maxFit = 1;
|
||||
while (maxFit < MAX_SCALE &&
|
||||
viewport.x / (maxFit + 1) >= MIN_UI_SIZE.x &&
|
||||
viewport.y / (maxFit + 1) >= MIN_UI_SIZE.y) {
|
||||
maxFit++;
|
||||
}
|
||||
return maxFit;
|
||||
}
|
||||
|
||||
int GUI::calcScale(const glm::uvec2& viewport) const {
|
||||
int maxFit = calcMaxScale(viewport);
|
||||
int value = engine.getSettings().display.guiScale.get();
|
||||
if (value <= 0) {
|
||||
return maxFit; // auto
|
||||
|
|
@ -111,6 +116,10 @@ int GUI::getScale() const {
|
|||
return scale;
|
||||
}
|
||||
|
||||
int GUI::getMaxScale() const {
|
||||
return calcMaxScale(engine.getWindow().getSize());
|
||||
}
|
||||
|
||||
CursorState GUI::getCursor() const {
|
||||
auto cursor = input.getCursor();
|
||||
cursor.pos /= static_cast<float>(scale);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ namespace gui {
|
|||
bool doubleClicked = false;
|
||||
bool debug = false;
|
||||
|
||||
static int calcMaxScale(const glm::uvec2& viewport);
|
||||
int calcScale(const glm::uvec2& viewport) const;
|
||||
CursorState getScaledCursor() const;
|
||||
|
||||
|
|
@ -134,6 +135,9 @@ namespace gui {
|
|||
/// @brief Get current GUI scale: window pixels per one UI unit
|
||||
int getScale() const;
|
||||
|
||||
/// @brief Get maximal GUI scale that fits the current window size
|
||||
int getMaxScale() const;
|
||||
|
||||
/// @brief Get cursor state in UI coordinates
|
||||
CursorState getCursor() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void InventoryBuilder::addGrid(
|
|||
if (addpanel) {
|
||||
auto panel =
|
||||
std::make_shared<gui::Container>(gui, glm::vec2(width, height));
|
||||
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f));
|
||||
view->setColor(InventoryView::DEFAULT_COLOR);
|
||||
view->add(panel, pos);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@ namespace gui {
|
|||
|
||||
static const int SLOT_INTERVAL = 4;
|
||||
static const int SLOT_SIZE = ITEM_ICON_SIZE;
|
||||
/// @brief Default background color (can be overridden by 'color' attribute)
|
||||
static inline const glm::vec4 DEFAULT_COLOR {0.122f, 0.122f, 0.122f, 0.878f};
|
||||
};
|
||||
|
||||
class InventoryBuilder {
|
||||
|
|
|
|||
|
|
@ -860,7 +860,7 @@ static std::shared_ptr<UINode> read_inventory(
|
|||
UiXmlReader& reader, const xml::xmlelement& element
|
||||
) {
|
||||
auto view = std::make_shared<InventoryView>(reader.getGUI());
|
||||
view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f)); // TODO: fixme
|
||||
view->setColor(InventoryView::DEFAULT_COLOR);
|
||||
reader.addIgnore("slot");
|
||||
reader.addIgnore("slots-grid");
|
||||
reader.readUINode(reader, element, *view);
|
||||
|
|
|
|||
|
|
@ -1067,6 +1067,20 @@ static int l_gui_getviewport(lua::State* L) {
|
|||
return lua::pushvec2(L, engine->getGUI().getContainer()->getSize());
|
||||
}
|
||||
|
||||
static int l_gui_get_scale(lua::State* L) {
|
||||
return lua::pushinteger(L, engine->getGUI().getScale());
|
||||
}
|
||||
|
||||
static int l_gui_get_max_scale(lua::State* L) {
|
||||
return lua::pushinteger(L, engine->getGUI().getMaxScale());
|
||||
}
|
||||
|
||||
static int l_gui_get_cursor_pos(lua::State* L) {
|
||||
if (engine->isHeadless())
|
||||
return 0;
|
||||
return lua::pushvec2(L, engine->getGUI().getCursor().pos);
|
||||
}
|
||||
|
||||
static int l_gui_clear_markup(lua::State* L) {
|
||||
auto lang = lua::require_string(L, 1);
|
||||
std::string text = lua::require_string(L, 2);
|
||||
|
|
@ -1247,6 +1261,9 @@ static int l_screenshot(lua::State* L) {
|
|||
const luaL_Reg guilib[] = {
|
||||
{"screenshot", lua::wrap<l_screenshot>},
|
||||
{"get_viewport", lua::wrap<l_gui_getviewport>},
|
||||
{"get_scale", lua::wrap<l_gui_get_scale>},
|
||||
{"get_max_scale", lua::wrap<l_gui_get_max_scale>},
|
||||
{"get_cursor_pos", lua::wrap<l_gui_get_cursor_pos>},
|
||||
{"getattr", lua::wrap<l_gui_getattr>},
|
||||
{"setattr", lua::wrap<l_gui_setattr>},
|
||||
{"get_env", lua::wrap<l_gui_get_env>},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue