mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-29 10:43:21 +08:00
added text widgets to dev-console tabs python api
This commit is contained in:
parent
d85ac6a160
commit
9fcc313b0b
40
.efrocachemap
generated
40
.efrocachemap
generated
@ -4056,26 +4056,26 @@
|
||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "5979fc1374865abb96a8ff2e3f44c166",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "b389b9d4d3cac1d18dc6c04d266d444e",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "9446081855fe37326f970d0ab43e2e59",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "1527bc05d69edeb8af30c6ab25b928f0",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c57b7f45564dd7cbb3f25c28266a5a3a",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "54911f2b25836bf38f8a33e306dcdee2",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "9f887dfab9eb196ee8a9ff5d7f876139",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "7f89a9b77feb1cde4ba611f4dd8bb444",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b52a34026a36769640de84ae94ac94d3",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "3c90aa7a5828921da6fa2d1b0242c76a",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f057fa1a420d0d23e6a5ccfa29a5cd2b",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "24ca0d3ddbe3c45870de1167cd92459a",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "eddb8691d13480b147baf732428139ca",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "9b276bef34a259e05c23391fa3d372a6",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "789d66ae2c844d81f3d4929cc6caf950",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "9fe031c292167461bd8790f11c1b78c6",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "461d3623b1d047a81000bf91f2b5095d",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "57fa8e653ccd0625fa6a95ba7cbcc089",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "7c9ef4e375fcfa593ea8ebdb2cb59f8e",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "d6e492d84f592d0547878c7de8b60e35",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "53125d7d6bd34fdfe78880773272237b",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "804a8aa64c159a3812a31be3df3584b1",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "655d8bc1d591917d7bbec7ffed98a5a7",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "9830f4dac6f35121b19db8e2f332d87c",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "7a360065ea427f2d44f1db6d550becfb",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "dd5b6769d2e95c93aae7126c8bdd3ffe",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "791b43e652365874eb136b7ec147f9e8",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "8d3fe48c1a1b601aa97ce33e892f5163",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "12d92655438f34e912e1525991df1f73",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "e39556a0047b65919b61c740e096e967",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "ae3a622c7fe0bddc6badba38402284fd",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "1e744c3641f603e22b55882f96fb0a86",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "bcbb650a041317c7788a31525a7c2d02",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "a84d2e36cb685224749f556d5ba857a5",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "beeecfee397c12e4c7193391973873f7",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "f186772de8396573ca7daa4f765ac63a",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "ada072c442da241991d2de9ad35abf79",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "52a2e2a3bd751f941069d4d007d7bc59",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "82d428e93227eafc8c8ffcb6e24d1ec0",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "567cac9a0ba532234fedb35a9bdd51a3",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "6ce4983e76e1cc2d2803fe306d08ad58",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "4ea0cf78901f994215f215aebb0af1dc",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "6ce4983e76e1cc2d2803fe306d08ad58",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
### 1.7.28 (build 21406, api 8, 2023-10-02)
|
||||
### 1.7.28 (build 21407, api 8, 2023-10-02)
|
||||
|
||||
- Massively cleaned up code related to rendering and window systems (OpenGL,
|
||||
SDL, etc). This code had been growing into a nasty tangle for 15 years
|
||||
@ -37,6 +37,9 @@
|
||||
etc.)
|
||||
- The in-app Python console text is now sized up on phone and tablet devices,
|
||||
and is generally a bit larger everywhere.
|
||||
- Added an API to define DevConsole tabs via Python. Currently it supports basic
|
||||
buttons and text, but should be easy to expand to whatever we need. See
|
||||
`babase/_devconsole.py`. It should be easy to define new tabs via plugins/etc.
|
||||
- Cleaned up onscreen keyboard support and generalized it to make it possible to
|
||||
support other things besides widgets and to make it easier to implement on
|
||||
other platforms.
|
||||
|
||||
@ -49,6 +49,21 @@ class DevConsoleTab:
|
||||
style,
|
||||
)
|
||||
|
||||
def text(
|
||||
self,
|
||||
text: str,
|
||||
pos: tuple[float, float],
|
||||
h_anchor: Literal['left', 'center', 'right'] = 'center',
|
||||
h_align: Literal['left', 'center', 'right'] = 'center',
|
||||
v_align: Literal['top', 'center', 'bottom', 'none'] = 'center',
|
||||
scale: float = 1.0,
|
||||
) -> None:
|
||||
"""Add a button to the tab being refreshed."""
|
||||
assert _babase.app.devconsole.is_refreshing
|
||||
_babase.dev_console_add_text(
|
||||
text, pos[0], pos[1], h_anchor, h_align, v_align, scale
|
||||
)
|
||||
|
||||
def python_terminal(self) -> None:
|
||||
"""Add a Python Terminal to the tab being refreshed."""
|
||||
assert _babase.app.devconsole.is_refreshing
|
||||
@ -95,6 +110,7 @@ class DevConsoleTabTest(DevConsoleTab):
|
||||
pos=(10, 10),
|
||||
size=(100, 30),
|
||||
h_anchor='left',
|
||||
label_scale=0.6,
|
||||
call=self.request_refresh,
|
||||
)
|
||||
self.button(
|
||||
@ -102,8 +118,17 @@ class DevConsoleTabTest(DevConsoleTab):
|
||||
pos=(120, 10),
|
||||
size=(100, 30),
|
||||
h_anchor='left',
|
||||
label_scale=0.6,
|
||||
style='dark',
|
||||
)
|
||||
self.text(
|
||||
'TestText',
|
||||
scale=0.8,
|
||||
pos=(15, 50),
|
||||
h_anchor='left',
|
||||
h_align='left',
|
||||
v_align='none',
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -115,7 +140,15 @@ class DevConsoleTabEntry:
|
||||
|
||||
|
||||
class DevConsoleSubsystem:
|
||||
"""Wrangles the dev console."""
|
||||
"""Subsystem for wrangling the dev console.
|
||||
|
||||
The single instance of this class can be found at
|
||||
babase.app.devconsole. The dev-console is a simple always-available
|
||||
UI intended for use by developers; not end users. Traditionally it
|
||||
is available by typing a backtick (`) key on a keyboard, but now can
|
||||
be accessed via an on-screen button (see settings/advanced to enable
|
||||
said button).
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
# All tabs in the dev-console. Add your own stuff here via
|
||||
|
||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21406
|
||||
TARGET_BALLISTICA_BUILD = 21407
|
||||
TARGET_BALLISTICA_VERSION = '1.7.28'
|
||||
|
||||
|
||||
|
||||
@ -1501,6 +1501,48 @@ static PyMethodDef PyDevConsoleAddButtonDef = {
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// ------------------------- dev_console_add_text ------------------------------
|
||||
|
||||
static auto PyDevConsoleAddText(PyObject* self, PyObject* args) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* dev_console = g_base->ui->dev_console();
|
||||
BA_PRECONDITION(dev_console);
|
||||
BA_PRECONDITION(dev_console->IsActive());
|
||||
const char* text;
|
||||
float x;
|
||||
float y;
|
||||
const char* h_anchor;
|
||||
const char* h_align;
|
||||
const char* v_align;
|
||||
float scale;
|
||||
if (!PyArg_ParseTuple(args, "sffsssf", &text, &x, &y, &h_anchor, &h_align,
|
||||
&v_align, &scale)) {
|
||||
return nullptr;
|
||||
}
|
||||
dev_console->AddText(text, x, y, h_anchor, h_align, v_align, scale);
|
||||
Py_RETURN_NONE;
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyDevConsoleAddTextDef = {
|
||||
"dev_console_add_text", // name
|
||||
(PyCFunction)PyDevConsoleAddText, // method
|
||||
METH_VARARGS, // flags
|
||||
|
||||
"dev_console_add_text(\n"
|
||||
" text: str,\n"
|
||||
" x: float,\n"
|
||||
" y: float,\n"
|
||||
" h_anchor: str,\n"
|
||||
" h_align: str,\n"
|
||||
" v_align: str,\n"
|
||||
" scale: float,\n"
|
||||
") -> None\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// -------------------- dev_console_add_python_terminal ------------------------
|
||||
|
||||
static auto PyDevConsoleAddPythonTerminal(PyObject* self, PyObject* args)
|
||||
@ -1673,6 +1715,7 @@ auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
|
||||
PyOpenDirExternallyDef,
|
||||
PyFatalErrorDef,
|
||||
PyDevConsoleAddButtonDef,
|
||||
PyDevConsoleAddTextDef,
|
||||
PyDevConsoleAddPythonTerminalDef,
|
||||
PyDevConsoleTabWidthDef,
|
||||
PyDevConsoleTabHeightDef,
|
||||
|
||||
@ -31,44 +31,102 @@ const int kDevConsoleActivateKey1 = SDLK_BACKQUOTE;
|
||||
const int kDevConsoleActivateKey2 = SDLK_F2;
|
||||
const float kDevConsoleTabButtonCornerRadius{16.0f};
|
||||
|
||||
const double kTransitionSeconds = 0.1;
|
||||
const double kTransitionSeconds = 0.15;
|
||||
|
||||
enum class DevButtonAttach_ { kLeft, kCenter, kRight };
|
||||
enum class DevConsoleHAnchor_ { kLeft, kCenter, kRight };
|
||||
enum class DevButtonStyle_ { kNormal, kDark };
|
||||
|
||||
static auto XOffs(DevButtonAttach_ attach) -> float {
|
||||
static auto DevButtonStyleFromStr_(const char* strval) {
|
||||
if (!strcmp(strval, "dark")) {
|
||||
return DevButtonStyle_::kDark;
|
||||
}
|
||||
assert(!strcmp(strval, "normal"));
|
||||
return DevButtonStyle_::kNormal;
|
||||
}
|
||||
|
||||
static auto DevConsoleHAttachFromStr_(const char* strval) {
|
||||
if (!strcmp(strval, "left")) {
|
||||
return DevConsoleHAnchor_::kLeft;
|
||||
} else if (!strcmp(strval, "right")) {
|
||||
return DevConsoleHAnchor_::kRight;
|
||||
}
|
||||
assert(!strcmp(strval, "center"));
|
||||
return DevConsoleHAnchor_::kCenter;
|
||||
}
|
||||
|
||||
static auto TextMeshHAlignFromStr_(const char* strval) {
|
||||
if (!strcmp(strval, "left")) {
|
||||
return TextMesh::HAlign::kLeft;
|
||||
} else if (!strcmp(strval, "right")) {
|
||||
return TextMesh::HAlign::kRight;
|
||||
}
|
||||
assert(!strcmp(strval, "center"));
|
||||
return TextMesh::HAlign::kCenter;
|
||||
}
|
||||
|
||||
static auto TextMeshVAlignFromStr_(const char* strval) {
|
||||
if (!strcmp(strval, "top")) {
|
||||
return TextMesh::VAlign::kTop;
|
||||
} else if (!strcmp(strval, "bottom")) {
|
||||
return TextMesh::VAlign::kBottom;
|
||||
} else if (!strcmp(strval, "none")) {
|
||||
return TextMesh::VAlign::kNone;
|
||||
}
|
||||
assert(!strcmp(strval, "center"));
|
||||
return TextMesh::VAlign::kCenter;
|
||||
}
|
||||
|
||||
static auto XOffs(DevConsoleHAnchor_ attach) -> float {
|
||||
switch (attach) {
|
||||
case DevButtonAttach_::kLeft:
|
||||
case DevConsoleHAnchor_::kLeft:
|
||||
return 0.0f;
|
||||
case DevButtonAttach_::kRight:
|
||||
case DevConsoleHAnchor_::kRight:
|
||||
return g_base->graphics->screen_virtual_width();
|
||||
case DevButtonAttach_::kCenter:
|
||||
case DevConsoleHAnchor_::kCenter:
|
||||
return g_base->graphics->screen_virtual_width() * 0.5f;
|
||||
}
|
||||
assert(false);
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
static void DrawBasicButton(RenderPass* pass, Mesh* mesh, TextGroup* tgrp,
|
||||
float tscale, float bottom, float x, float y,
|
||||
float width, float height, const Vector3f& fgcolor,
|
||||
const Vector3f& bgcolor) {
|
||||
static void DrawRect(RenderPass* pass, Mesh* mesh, float bottom, float x,
|
||||
float y, float width, float height,
|
||||
const Vector3f& bgcolor) {
|
||||
SimpleComponent c(pass);
|
||||
c.SetTransparent(true);
|
||||
c.SetColor(bgcolor.x, bgcolor.y, bgcolor.z, 1.0f);
|
||||
c.SetTexture(g_base->assets->SysTexture(SysTextureID::kCircle));
|
||||
{
|
||||
// Draw mesh bg.
|
||||
if (mesh) {
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(x, y + bottom, kDevConsoleZDepth);
|
||||
c.DrawMesh(mesh);
|
||||
}
|
||||
// Draw our text.
|
||||
// Draw text.
|
||||
// {
|
||||
// auto xf = c.ScopedTransform();
|
||||
// c.Translate(x + width * 0.5f, y + bottom + height * 0.5f,
|
||||
// kDevConsoleZDepth);
|
||||
// c.Scale(tscale, tscale, 1.0f);
|
||||
// int elem_count = tgrp->GetElementCount();
|
||||
// c.SetColor(fgcolor.x, fgcolor.y, fgcolor.z, 1.0f);
|
||||
// c.SetFlatness(1.0f);
|
||||
// for (int e = 0; e < elem_count; e++) {
|
||||
// c.SetTexture(tgrp->GetElementTexture(e));
|
||||
// c.DrawMesh(tgrp->GetElementMesh(e));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
static void DrawText(RenderPass* pass, TextGroup* tgrp, float tscale,
|
||||
float bottom, float x, float y, const Vector3f& fgcolor) {
|
||||
SimpleComponent c(pass);
|
||||
c.SetTransparent(true);
|
||||
// Draw text.
|
||||
{
|
||||
auto xf = c.ScopedTransform();
|
||||
c.Translate(x + width * 0.5f, y + bottom + height * 0.5f,
|
||||
kDevConsoleZDepth);
|
||||
float sc{0.6f * tscale};
|
||||
c.Scale(sc, sc, 1.0f);
|
||||
c.Translate(x, y + bottom, kDevConsoleZDepth);
|
||||
c.Scale(tscale, tscale, 1.0f);
|
||||
int elem_count = tgrp->GetElementCount();
|
||||
c.SetColor(fgcolor.x, fgcolor.y, fgcolor.z, 1.0f);
|
||||
c.SetFlatness(1.0f);
|
||||
@ -84,14 +142,46 @@ static void DrawBasicButton(RenderPass* pass, Mesh* mesh, TextGroup* tgrp,
|
||||
class DevConsole::Widget_ {
|
||||
public:
|
||||
virtual ~Widget_() = default;
|
||||
virtual auto HandleMouseDown(float mx, float my) -> bool = 0;
|
||||
virtual void HandleMouseUp(float mx, float my) = 0;
|
||||
virtual auto HandleMouseDown(float mx, float my) -> bool { return false; }
|
||||
virtual void HandleMouseUp(float mx, float my) {}
|
||||
virtual void Draw(RenderPass* pass, float bottom) = 0;
|
||||
};
|
||||
|
||||
class DevConsole::Text_ : public DevConsole::Widget_ {
|
||||
public:
|
||||
DevConsoleHAnchor_ h_attach;
|
||||
TextMesh::HAlign h_align;
|
||||
TextMesh::VAlign v_align;
|
||||
float x;
|
||||
float y;
|
||||
float scale;
|
||||
TextGroup text_group;
|
||||
DevButtonStyle_ style;
|
||||
|
||||
Text_(const std::string& text, float x, float y, DevConsoleHAnchor_ h_attach,
|
||||
TextMesh::HAlign h_align, TextMesh::VAlign v_align, float scale)
|
||||
: h_attach{h_attach},
|
||||
h_align(h_align),
|
||||
v_align(v_align),
|
||||
x{x},
|
||||
y{y},
|
||||
scale{scale} {
|
||||
text_group.SetText(text, h_align, v_align);
|
||||
}
|
||||
|
||||
void Draw(RenderPass* pass, float bottom) override {
|
||||
Vector3f fgcolor;
|
||||
Vector3f bgcolor;
|
||||
fgcolor = Vector3f{0.8f, 0.7f, 0.8f};
|
||||
bgcolor = Vector3f{0.25, 0.2f, 0.3f};
|
||||
|
||||
DrawText(pass, &text_group, scale, bottom, x + XOffs(h_attach), y, fgcolor);
|
||||
}
|
||||
};
|
||||
|
||||
class DevConsole::Button_ : public DevConsole::Widget_ {
|
||||
public:
|
||||
DevButtonAttach_ attach;
|
||||
DevConsoleHAnchor_ attach;
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
@ -104,7 +194,7 @@ class DevConsole::Button_ : public DevConsole::Widget_ {
|
||||
DevButtonStyle_ style;
|
||||
|
||||
template <typename F>
|
||||
Button_(const std::string& label, float text_scale, DevButtonAttach_ attach,
|
||||
Button_(const std::string& label, float text_scale, DevConsoleHAnchor_ attach,
|
||||
float x, float y, float width, float height, float corner_radius,
|
||||
DevButtonStyle_ style, const F& lambda)
|
||||
: attach{attach},
|
||||
@ -165,14 +255,15 @@ class DevConsole::Button_ : public DevConsole::Widget_ {
|
||||
bgcolor =
|
||||
pressed ? Vector3f{0.8f, 0.7f, 0.8f} : Vector3f{0.25, 0.2f, 0.3f};
|
||||
}
|
||||
DrawBasicButton(pass, &mesh, &text_group, text_scale, bottom,
|
||||
x + XOffs(attach), y, width, height, fgcolor, bgcolor);
|
||||
DrawRect(pass, &mesh, bottom, x + XOffs(attach), y, width, height, bgcolor);
|
||||
DrawText(pass, &text_group, text_scale, bottom,
|
||||
x + XOffs(attach) + width * 0.5f, y + height * 0.5f, fgcolor);
|
||||
}
|
||||
};
|
||||
|
||||
class DevConsole::ToggleButton_ : public DevConsole::Widget_ {
|
||||
public:
|
||||
DevButtonAttach_ attach;
|
||||
DevConsoleHAnchor_ attach;
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
@ -187,7 +278,7 @@ class DevConsole::ToggleButton_ : public DevConsole::Widget_ {
|
||||
|
||||
template <typename F, typename G>
|
||||
ToggleButton_(const std::string& label, float text_scale,
|
||||
DevButtonAttach_ attach, float x, float y, float width,
|
||||
DevConsoleHAnchor_ attach, float x, float y, float width,
|
||||
float height, float corner_radius, const F& on_call,
|
||||
const G& off_call)
|
||||
: attach{attach},
|
||||
@ -234,20 +325,22 @@ class DevConsole::ToggleButton_ : public DevConsole::Widget_ {
|
||||
}
|
||||
|
||||
void Draw(RenderPass* pass, float bottom) override {
|
||||
DrawBasicButton(pass, &mesh, &text_group, text_scale, bottom,
|
||||
x + XOffs(attach), y, width, height,
|
||||
pressed ? Vector3f{1.0f, 1.0f, 1.0f}
|
||||
: on ? Vector3f{1.0f, 1.0f, 1.0f}
|
||||
: Vector3f{0.8f, 0.7f, 0.8f},
|
||||
pressed ? Vector3f{0.5f, 0.2f, 1.0f}
|
||||
: on ? Vector3f{0.5f, 0.4f, 0.6f}
|
||||
: Vector3f{0.25, 0.2f, 0.3f});
|
||||
DrawRect(pass, &mesh, bottom, x + XOffs(attach), y, width, height,
|
||||
|
||||
pressed ? Vector3f{0.5f, 0.2f, 1.0f}
|
||||
: on ? Vector3f{0.5f, 0.4f, 0.6f}
|
||||
: Vector3f{0.25, 0.2f, 0.3f});
|
||||
DrawText(pass, &text_group, text_scale, bottom,
|
||||
x + XOffs(attach) + width * 0.5f, y + height * 0.5f,
|
||||
pressed ? Vector3f{1.0f, 1.0f, 1.0f}
|
||||
: on ? Vector3f{1.0f, 1.0f, 1.0f}
|
||||
: Vector3f{0.8f, 0.7f, 0.8f});
|
||||
}
|
||||
};
|
||||
|
||||
class DevConsole::TabButton_ : public DevConsole::Widget_ {
|
||||
public:
|
||||
DevButtonAttach_ attach;
|
||||
DevConsoleHAnchor_ attach;
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
@ -261,7 +354,7 @@ class DevConsole::TabButton_ : public DevConsole::Widget_ {
|
||||
|
||||
template <typename F>
|
||||
TabButton_(const std::string& label, bool selected, float text_scale,
|
||||
DevButtonAttach_ attach, float x, float y, float width,
|
||||
DevConsoleHAnchor_ attach, float x, float y, float width,
|
||||
float height, const F& call)
|
||||
: attach{attach},
|
||||
x{x},
|
||||
@ -308,15 +401,15 @@ class DevConsole::TabButton_ : public DevConsole::Widget_ {
|
||||
}
|
||||
|
||||
void Draw(RenderPass* pass, float bottom) override {
|
||||
DrawBasicButton(pass, &mesh, &text_group, text_scale, bottom,
|
||||
x + XOffs(attach), y, width, height,
|
||||
pressed ? Vector3f{1.0f, 1.0f, 1.0f}
|
||||
: selected ? Vector3f{1.0f, 1.0f, 1.0f}
|
||||
: Vector3f{0.6f, 0.5f, 0.6f},
|
||||
pressed ? Vector3f{0.4f, 0.2f, 0.8f}
|
||||
: selected ? Vector3f{0.4f, 0.3f, 0.4f}
|
||||
// : selected ? Vector3f{0.5f, 0.4f, 0.6f}
|
||||
: Vector3f{0.25, 0.2f, 0.3f});
|
||||
DrawRect(pass, &mesh, bottom, x + XOffs(attach), y, width, height,
|
||||
pressed ? Vector3f{0.4f, 0.2f, 0.8f}
|
||||
: selected ? Vector3f{0.4f, 0.3f, 0.4f}
|
||||
: Vector3f{0.25, 0.2f, 0.3f});
|
||||
DrawText(pass, &text_group, text_scale, bottom,
|
||||
x + XOffs(attach) + width * 0.5f, y + height * 0.5f,
|
||||
pressed ? Vector3f{1.0f, 1.0f, 1.0f}
|
||||
: selected ? Vector3f{1.0f, 1.0f, 1.0f}
|
||||
: Vector3f{0.6f, 0.5f, 0.6f});
|
||||
}
|
||||
};
|
||||
|
||||
@ -381,13 +474,13 @@ void DevConsole::RefreshTabButtons_() {
|
||||
float bs = BaseScale();
|
||||
float bwidth = 90.0f * bs;
|
||||
float bheight = 26.0f * bs;
|
||||
float bscale = 0.8f * bs;
|
||||
float bscale = 0.6f * bs;
|
||||
float total_width = tabs_.size() * bwidth;
|
||||
float x = total_width * -0.5f;
|
||||
for (auto&& tab : tabs_) {
|
||||
tab_buttons_.emplace_back(std::make_unique<TabButton_>(
|
||||
tab, active_tab_ == tab, bscale, DevButtonAttach_::kCenter, x, -bheight,
|
||||
bwidth, bheight, [this, tab] {
|
||||
tab, active_tab_ == tab, bscale, DevConsoleHAnchor_::kCenter, x,
|
||||
-bheight, bwidth, bheight, [this, tab] {
|
||||
active_tab_ = tab;
|
||||
RefreshTabButtons_();
|
||||
RefreshTabContents_();
|
||||
@ -404,7 +497,7 @@ void DevConsole::RefreshTabContents_() {
|
||||
refresh_pending_ = false;
|
||||
|
||||
// Clear to an empty slate.
|
||||
buttons_.clear();
|
||||
widgets_.clear();
|
||||
python_terminal_visible_ = false;
|
||||
|
||||
// Now ask the Python layer to fill this tab in.
|
||||
@ -414,43 +507,39 @@ void DevConsole::RefreshTabContents_() {
|
||||
.Call(args);
|
||||
}
|
||||
|
||||
void DevConsole::AddText(const char* text, float x, float y,
|
||||
const char* h_anchor_str, const char* h_align_str,
|
||||
const char* v_align_str, float scale) {
|
||||
auto h_anchor = DevConsoleHAttachFromStr_(h_anchor_str);
|
||||
auto h_align = TextMeshHAlignFromStr_(h_align_str);
|
||||
auto v_align = TextMeshVAlignFromStr_(v_align_str);
|
||||
|
||||
widgets_.emplace_back(
|
||||
std::make_unique<Text_>(text, x, y, h_anchor, h_align, v_align, scale));
|
||||
}
|
||||
|
||||
void DevConsole::AddButton(const char* label, float x, float y, float width,
|
||||
float height, PyObject* call, const char* h_anchor,
|
||||
float label_scale, float corner_radius,
|
||||
const char* style) {
|
||||
float height, PyObject* call,
|
||||
const char* h_anchor_str, float label_scale,
|
||||
float corner_radius, const char* style_str) {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
DevButtonStyle_ style_val;
|
||||
if (!strcmp(style, "dark")) {
|
||||
style_val = DevButtonStyle_::kDark;
|
||||
} else {
|
||||
style_val = DevButtonStyle_::kNormal;
|
||||
}
|
||||
auto style = DevButtonStyleFromStr_(style_str);
|
||||
auto h_anchor = DevConsoleHAttachFromStr_(h_anchor_str);
|
||||
|
||||
DevButtonAttach_ anchor;
|
||||
if (!strcmp(h_anchor, "left")) {
|
||||
anchor = DevButtonAttach_::kLeft;
|
||||
} else if (!strcmp(h_anchor, "right")) {
|
||||
anchor = DevButtonAttach_::kRight;
|
||||
} else {
|
||||
assert(!strcmp(h_anchor, "center"));
|
||||
anchor = DevButtonAttach_::kCenter;
|
||||
}
|
||||
|
||||
// auto call_obj = PythonRef::Acquired(call);
|
||||
buttons_.emplace_back(std::make_unique<Button_>(
|
||||
label, label_scale, anchor, x, y, width, height, corner_radius, style_val,
|
||||
[this, call_obj = PythonRef::Acquired(call)] {
|
||||
if (call_obj.Get() != Py_None) {
|
||||
call_obj.Call();
|
||||
widgets_.emplace_back(std::make_unique<Button_>(
|
||||
label, label_scale, h_anchor, x, y, width, height, corner_radius, style,
|
||||
[this, callref = PythonRef::Acquired(call)] {
|
||||
if (callref.Get() != Py_None) {
|
||||
callref.Call();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void DevConsole::AddPythonTerminal() {
|
||||
float bs = BaseScale();
|
||||
buttons_.emplace_back(std::make_unique<Button_>(
|
||||
"Exec", 0.75f * bs, DevButtonAttach_::kRight, -33.0f * bs, 15.95f * bs,
|
||||
widgets_.emplace_back(std::make_unique<Button_>(
|
||||
"Exec", 0.5f * bs, DevConsoleHAnchor_::kRight, -33.0f * bs, 15.95f * bs,
|
||||
32.0f * bs, 13.0f * bs, 2.0 * bs, DevButtonStyle_::kNormal,
|
||||
[this] { Exec(); }));
|
||||
python_terminal_visible_ = true;
|
||||
@ -483,7 +572,7 @@ auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (auto&& button : buttons_) {
|
||||
for (auto&& button : widgets_) {
|
||||
if (button->HandleMouseDown(x, y - bottom)) {
|
||||
return true;
|
||||
}
|
||||
@ -517,7 +606,7 @@ void DevConsole::HandleMouseUp(int button, float x, float y) {
|
||||
for (auto&& button : tab_buttons_) {
|
||||
button->HandleMouseUp(x, y - bottom);
|
||||
}
|
||||
for (auto&& button : buttons_) {
|
||||
for (auto&& button : widgets_) {
|
||||
button->HandleMouseUp(x, y - bottom);
|
||||
}
|
||||
}
|
||||
@ -800,6 +889,10 @@ auto DevConsole::Bottom_() const -> float {
|
||||
// more important for them to be able to be written to a known hard-coded
|
||||
// mini-size.
|
||||
float mini_size = 100.0f;
|
||||
|
||||
// Now that we have tabs and drop-shadows hanging down, we have to
|
||||
// overshoot the top of the screen when transitioning out.
|
||||
float top_buffer = 100.0f;
|
||||
if (state_ == State_::kMini) {
|
||||
bottom = vh - mini_size;
|
||||
} else {
|
||||
@ -812,7 +905,7 @@ auto DevConsole::Bottom_() const -> float {
|
||||
} else if (state_prev_ == State_::kFull) {
|
||||
from_height = vh - vh * kDevConsoleSize;
|
||||
} else {
|
||||
from_height = vh;
|
||||
from_height = vh + top_buffer;
|
||||
}
|
||||
float to_height;
|
||||
if (state_ == State_::kMini) {
|
||||
@ -820,7 +913,7 @@ auto DevConsole::Bottom_() const -> float {
|
||||
} else if (state_ == State_::kFull) {
|
||||
to_height = vh - vh * kDevConsoleSize;
|
||||
} else {
|
||||
to_height = vh;
|
||||
to_height = vh + top_buffer;
|
||||
}
|
||||
bottom = to_height * ratio + from_height * (1.0 - ratio);
|
||||
}
|
||||
@ -852,19 +945,20 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
border_mesh_.SetPositionAndSize(0, bottom - border_height * bs,
|
||||
kDevConsoleZDepth, pass->virtual_width(),
|
||||
border_height * bs);
|
||||
SimpleComponent c(pass);
|
||||
c.SetTransparent(true);
|
||||
c.SetColor(0, 0, 0.1f, 0.9f);
|
||||
c.DrawMesh(&bg_mesh_);
|
||||
c.Submit();
|
||||
if (python_terminal_visible_) {
|
||||
c.SetColor(1.0f, 1.0f, 1.0f, 0.1f);
|
||||
c.DrawMesh(&stripe_mesh_);
|
||||
{
|
||||
SimpleComponent c(pass);
|
||||
c.SetTransparent(true);
|
||||
c.SetColor(0, 0, 0.1f, 0.9f);
|
||||
c.DrawMesh(&bg_mesh_);
|
||||
c.Submit();
|
||||
if (python_terminal_visible_) {
|
||||
c.SetColor(1.0f, 1.0f, 1.0f, 0.1f);
|
||||
c.DrawMesh(&stripe_mesh_);
|
||||
c.Submit();
|
||||
}
|
||||
c.SetColor(0.25f, 0.2f, 0.3f, 1.0f);
|
||||
c.DrawMesh(&border_mesh_);
|
||||
}
|
||||
c.SetColor(0.25f, 0.2f, 0.3f, 1.0f);
|
||||
c.DrawMesh(&border_mesh_);
|
||||
c.Submit();
|
||||
}
|
||||
|
||||
// Drop shadow.
|
||||
@ -936,7 +1030,6 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
c.DrawMesh(input_text_group_.GetElementMesh(e));
|
||||
}
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
|
||||
// Carat.
|
||||
@ -956,17 +1049,16 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
c.Scale(6.0f * bs, 12.0f * bs, 1.0f);
|
||||
c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1));
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
|
||||
// Draw output lines.
|
||||
// Output lines.
|
||||
{
|
||||
float draw_scale = 0.6f;
|
||||
float v_inc = 18.0f;
|
||||
SimpleComponent c(pass);
|
||||
c.SetTransparent(true);
|
||||
c.SetColor(1, 1, 1, 1);
|
||||
c.SetFlatness(1.0f);
|
||||
float draw_scale = 0.6f;
|
||||
float v_inc = 18.0f;
|
||||
float h = 0.5f
|
||||
* (g_base->graphics->screen_virtual_width()
|
||||
- (kDevConsoleStringBreakUpSize * draw_scale));
|
||||
@ -1007,7 +1099,6 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
c.Submit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1020,7 +1111,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
|
||||
// Buttons.
|
||||
{
|
||||
for (auto&& button : buttons_) {
|
||||
for (auto&& button : widgets_) {
|
||||
button->Draw(pass, bottom);
|
||||
}
|
||||
}
|
||||
@ -1040,4 +1131,21 @@ auto DevConsole::BaseScale() const -> float {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void DevConsole::StepDisplayTime() {
|
||||
assert(g_base->InLogicThread());
|
||||
// If we're inactive, blow away all our stuff once we transition fully
|
||||
// off screen. This will kill any Python stuff attached to our widgets
|
||||
// so things can clean themselves up.
|
||||
if (state_ == State_::kInactive && !tab_buttons_.empty()) {
|
||||
if ((g_base->logic->display_time() - transition_start_)
|
||||
>= kTransitionSeconds) {
|
||||
// Reset to a blank slate but *don't refresh anything (that will
|
||||
// happen once we get vis'ed again).
|
||||
tab_buttons_.clear();
|
||||
widgets_.clear();
|
||||
python_terminal_visible_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ballistica::base
|
||||
|
||||
@ -37,6 +37,8 @@ class DevConsole {
|
||||
void Print(const std::string& s_in);
|
||||
void Draw(FrameDef* frame_def);
|
||||
|
||||
void StepDisplayTime();
|
||||
|
||||
/// Called when the console should start accepting Python command input.
|
||||
void EnableInput();
|
||||
|
||||
@ -53,8 +55,10 @@ class DevConsole {
|
||||
void Exec();
|
||||
|
||||
void AddButton(const char* label, float x, float y, float width, float height,
|
||||
PyObject* call, const char* h_anchor, float label_scale,
|
||||
float corner_radius, const char* style);
|
||||
PyObject* call, const char* h_anchor_str, float label_scale,
|
||||
float corner_radius, const char* style_str);
|
||||
void AddText(const char* text, float x, float y, const char* h_anchor_str,
|
||||
const char* h_align_str, const char* v_align_str, float scale);
|
||||
void AddPythonTerminal();
|
||||
|
||||
auto Width() -> float;
|
||||
@ -65,6 +69,7 @@ class DevConsole {
|
||||
private:
|
||||
class Widget_;
|
||||
class Button_;
|
||||
class Text_;
|
||||
class ToggleButton_;
|
||||
class TabButton_;
|
||||
class OutputLine_;
|
||||
@ -103,7 +108,7 @@ class DevConsole {
|
||||
Object::Ref<TextGroup> last_line_mesh_group_;
|
||||
std::list<std::string> input_history_;
|
||||
std::list<OutputLine_> output_lines_;
|
||||
std::vector<std::unique_ptr<Widget_> > buttons_;
|
||||
std::vector<std::unique_ptr<Widget_> > widgets_;
|
||||
std::vector<std::unique_ptr<Widget_> > tab_buttons_;
|
||||
};
|
||||
|
||||
|
||||
@ -49,7 +49,12 @@ UI::UI() {
|
||||
}
|
||||
}
|
||||
|
||||
void UI::StepDisplayTime() { assert(g_base->InLogicThread()); }
|
||||
void UI::StepDisplayTime() {
|
||||
assert(g_base->InLogicThread());
|
||||
if (dev_console_) {
|
||||
dev_console_->StepDisplayTime();
|
||||
}
|
||||
}
|
||||
|
||||
void UI::OnAppStart() {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kEngineBuildNumber = 21406;
|
||||
const int kEngineBuildNumber = 21407;
|
||||
const char* kEngineVersion = "1.7.28";
|
||||
const int kEngineApiVersion = 8;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user