Skip to content

Commit 3e42fa4

Browse files
committed
feat: add additional imgui funcs
1 parent 58c918f commit 3e42fa4

File tree

6 files changed

+332
-11
lines changed

6 files changed

+332
-11
lines changed

extensions/pl_dearimgui_ext_m.cpp

Lines changed: 216 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@ Index of this file:
3232
#define PY_SSIZE_T_CLEAN
3333
#include <Python.h>
3434
#include "imgui.h"
35+
#define PL_MATH_INCLUDE_FUNCTIONS
36+
#include "pl_math.h"
3537

3638
#include "pl_graphics_ext.h"
3739

3840
bool pl_parse(const char* formatstring, const char** keywords, PyObject* args, PyObject* kwargs, const char* message, ...);
41+
static ImVec2 pl__get_vec2_from_python(PyObject* ptValue);
3942

4043
typedef struct _plPythonIntConstantPair
4144
{
@@ -140,6 +143,27 @@ plImgui_render(PyObject* self, PyObject* args, PyObject* kwargs)
140143
Py_RETURN_NONE;
141144
}
142145

146+
PyObject*
147+
plImgui_StyleColorsDark(PyObject* self)
148+
{
149+
ImGui::StyleColorsDark();
150+
Py_RETURN_NONE;
151+
}
152+
153+
PyObject*
154+
plImgui_StyleColorsLight(PyObject* self)
155+
{
156+
ImGui::StyleColorsLight();
157+
Py_RETURN_NONE;
158+
}
159+
160+
PyObject*
161+
plImgui_StyleColorsClassic(PyObject* self)
162+
{
163+
ImGui::StyleColorsClassic();
164+
Py_RETURN_NONE;
165+
}
166+
143167
PyObject*
144168
plImgui_cleanup(PyObject* self, PyObject* args, PyObject* kwargs)
145169
{
@@ -172,7 +196,7 @@ plImPlot_ShowDemoWindow(PyObject* self, PyObject* arg)
172196
}
173197

174198
PyObject*
175-
plImgui_begin(PyObject* self, PyObject* args, PyObject* kwargs)
199+
plImgui_Begin(PyObject* self, PyObject* args, PyObject* kwargs)
176200
{
177201

178202
static const char* apcKeywords[] = {
@@ -196,12 +220,135 @@ plImgui_begin(PyObject* self, PyObject* args, PyObject* kwargs)
196220
}
197221

198222
PyObject*
199-
plImgui_end(PyObject* self)
223+
plImgui_End(PyObject* self)
200224
{
201225
ImGui::End();
202226
Py_RETURN_NONE;
203227
}
204228

229+
PyObject*
230+
plImgui_Button(PyObject* self, PyObject* args, PyObject* kwargs)
231+
{
232+
233+
static const char* apcKeywords[] = {
234+
"label",
235+
"size",
236+
nullptr,
237+
};
238+
const char* pcLabel = nullptr;
239+
PyObject* ptSize = nullptr;
240+
if (!pl_parse("s|O", (const char**)apcKeywords, args, kwargs, __FUNCTION__,
241+
&pcLabel, &ptSize))
242+
return nullptr;
243+
244+
ImVec2 tSize = {};
245+
if(!Py_IsNone(ptSize))
246+
tSize = pl__get_vec2_from_python(ptSize);
247+
248+
return PyBool_FromLong(ImGui::Button(pcLabel, tSize));
249+
}
250+
251+
PyObject*
252+
plImgui_BeginMenuBar(PyObject* self)
253+
{
254+
return PyBool_FromLong(ImGui::BeginMenuBar());
255+
}
256+
257+
PyObject*
258+
plImgui_BeginMainMenuBar(PyObject* self)
259+
{
260+
return PyBool_FromLong(ImGui::BeginMainMenuBar());
261+
}
262+
263+
PyObject*
264+
plImgui_EndMenuBar(PyObject* self)
265+
{
266+
ImGui::EndMenuBar();
267+
Py_RETURN_NONE;
268+
}
269+
270+
PyObject*
271+
plImgui_EndMainMenuBar(PyObject* self)
272+
{
273+
ImGui::EndMainMenuBar();
274+
Py_RETURN_NONE;
275+
}
276+
277+
PyObject*
278+
plImgui_EndMenu(PyObject* self)
279+
{
280+
ImGui::EndMenu();
281+
Py_RETURN_NONE;
282+
}
283+
284+
PyObject*
285+
plImgui_BeginMenu(PyObject* self, PyObject* args, PyObject* kwargs)
286+
{
287+
288+
static const char* apcKeywords[] = {
289+
"label",
290+
"enabled",
291+
nullptr,
292+
};
293+
const char* pcLabel = nullptr;
294+
int bEnabled = true;
295+
if (!pl_parse("s|p", (const char**)apcKeywords, args, kwargs, __FUNCTION__,
296+
&pcLabel, &bEnabled))
297+
return nullptr;
298+
299+
return PyBool_FromLong(ImGui::BeginMenu(pcLabel, bEnabled));
300+
}
301+
302+
PyObject*
303+
plImgui_MenuItem(PyObject* self, PyObject* args, PyObject* kwargs)
304+
{
305+
306+
static const char* apcKeywords[] = {
307+
"label",
308+
"shortcut",
309+
"selected",
310+
"enabled",
311+
"selected_pointer",
312+
nullptr,
313+
};
314+
const char* pcLabel = nullptr;
315+
const char* pcShortcut = nullptr;
316+
int bEnabled = false;
317+
int bSelected = true;
318+
PyObject* ptPointer = nullptr;
319+
if (!pl_parse("s|spp$O", (const char**)apcKeywords, args, kwargs, __FUNCTION__,
320+
&pcLabel, &pcShortcut, &bSelected, &bEnabled, &ptPointer))
321+
return nullptr;
322+
323+
bool* pbSelected = nullptr;
324+
if(!Py_IsNone(ptPointer))
325+
pbSelected = (bool*)PyCapsule_GetPointer(ptPointer, "pb");
326+
327+
if(pbSelected)
328+
return PyBool_FromLong(ImGui::MenuItem(pcLabel, pcShortcut, pbSelected, bEnabled));
329+
return PyBool_FromLong(ImGui::MenuItem(pcLabel, pcShortcut, bSelected, bEnabled));
330+
}
331+
332+
PyObject*
333+
plImgui_Checkbox(PyObject* self, PyObject* args, PyObject* kwargs)
334+
{
335+
336+
static const char* apcKeywords[] = {
337+
"label",
338+
"value_pointer",
339+
nullptr,
340+
};
341+
const char* pcLabel = nullptr;
342+
PyObject* ptPointer = nullptr;
343+
if (!pl_parse("sO", (const char**)apcKeywords, args, kwargs, __FUNCTION__,
344+
&pcLabel, &ptPointer))
345+
return nullptr;
346+
347+
bool* pbSelected = (bool*)PyCapsule_GetPointer(ptPointer, "pb");
348+
349+
return PyBool_FromLong(ImGui::Checkbox(pcLabel, pbSelected));
350+
}
351+
205352

206353
#define PL_PYTHON_COMMAND(ARG, FLAGS, DOCS) {#ARG, (PyCFunction)ARG, FLAGS, DOCS}
207354
#define PL_ADD_INT_CONSTANT(X_ARG) {#X_ARG, X_ARG}
@@ -214,8 +361,24 @@ static PyMethodDef gatCommands[] =
214361
PL_PYTHON_COMMAND(plImgui_render, METH_VARARGS | METH_KEYWORDS, NULL),
215362
PL_PYTHON_COMMAND(plImgui_cleanup, METH_VARARGS | METH_KEYWORDS, NULL),
216363
PL_PYTHON_COMMAND(plImGui_ShowDemoWindow, METH_O, NULL),
217-
PL_PYTHON_COMMAND(plImgui_begin, METH_VARARGS | METH_KEYWORDS, NULL),
218-
PL_PYTHON_COMMAND(plImgui_end, METH_NOARGS, NULL),
364+
PL_PYTHON_COMMAND(plImgui_Begin, METH_VARARGS | METH_KEYWORDS, NULL),
365+
PL_PYTHON_COMMAND(plImgui_End, METH_NOARGS, NULL),
366+
PL_PYTHON_COMMAND(plImgui_StyleColorsDark, METH_NOARGS, NULL),
367+
PL_PYTHON_COMMAND(plImgui_StyleColorsLight, METH_NOARGS, NULL),
368+
PL_PYTHON_COMMAND(plImgui_StyleColorsClassic, METH_NOARGS, NULL),
369+
370+
// imgui widgets
371+
PL_PYTHON_COMMAND(plImgui_Button, METH_VARARGS | METH_KEYWORDS, NULL),
372+
373+
// imgui menus
374+
PL_PYTHON_COMMAND(plImgui_BeginMenuBar, METH_NOARGS, NULL),
375+
PL_PYTHON_COMMAND(plImgui_BeginMainMenuBar, METH_NOARGS, NULL),
376+
PL_PYTHON_COMMAND(plImgui_EndMenuBar, METH_NOARGS, NULL),
377+
PL_PYTHON_COMMAND(plImgui_EndMainMenuBar, METH_NOARGS, NULL),
378+
PL_PYTHON_COMMAND(plImgui_EndMenu, METH_NOARGS, NULL),
379+
PL_PYTHON_COMMAND(plImgui_BeginMenu, METH_VARARGS | METH_KEYWORDS, NULL),
380+
PL_PYTHON_COMMAND(plImgui_MenuItem, METH_VARARGS | METH_KEYWORDS, NULL),
381+
PL_PYTHON_COMMAND(plImgui_Checkbox, METH_VARARGS | METH_KEYWORDS, NULL),
219382

220383
// implot
221384
PL_PYTHON_COMMAND(plImPlot_ShowDemoWindow, METH_O, NULL),
@@ -299,4 +462,53 @@ pl_parse(const char* formatstring, const char** keywords, PyObject* args, PyObje
299462
// mvThrowPythonError(mvErrorCode::mvNone, "Error parsing Dear PyGui command: " + std::string(message));
300463

301464
return check;
465+
}
466+
467+
static ImVec2
468+
pl__get_vec2_from_python(PyObject* ptValue)
469+
{
470+
ImVec2 tResult = {};
471+
472+
if (PyTuple_Check(ptValue))
473+
{
474+
Py_ssize_t pySize = PyTuple_Size(ptValue);
475+
pySize = pl_min(pySize, 2);
476+
for (Py_ssize_t i = 0; i < pySize; ++i)
477+
{
478+
tResult[i] = (float)PyFloat_AsDouble(PyTuple_GetItem(ptValue, i));
479+
}
480+
}
481+
482+
else if (PyList_Check(ptValue))
483+
{
484+
Py_ssize_t pySize = PyList_Size(ptValue);
485+
pySize = pl_min(pySize, 2);
486+
for (Py_ssize_t i = 0; i < pySize; ++i)
487+
{
488+
tResult[i] = (float)PyFloat_AsDouble(PyList_GetItem(ptValue, i));
489+
}
490+
}
491+
492+
// else if (PyObject_CheckBuffer(ptValue))
493+
// {
494+
// Py_buffer buffer_info;
495+
496+
// if (!PyObject_GetBuffer(ptValue, &buffer_info,
497+
// PyBUF_CONTIG_RO | PyBUF_FORMAT))
498+
// {
499+
500+
// auto BufferViewer = BufferViewFunctionsFloat(buffer_info);
501+
// items.reserve(buffer_info.len / buffer_info.itemsize);
502+
503+
// for (Py_ssize_t i = 0; i < buffer_info.len / buffer_info.itemsize; ++i)
504+
// {
505+
// items.emplace_back(BufferViewer(buffer_info, i));
506+
// }
507+
// }
508+
// PyBuffer_Release(&buffer_info);
509+
// }
510+
// else
511+
// mvThrowPythonError(mvErrorCode::mvWrongType, "Python value error. Must be List[float].");
512+
513+
return tResult;
302514
}

pilotlight/pl_core.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ def create_bool_pointer():
5858
def destroy_bool_pointer(pointer):
5959
return internal.destroy_bool_pointer(pointer)
6060

61+
def create_int_pointer():
62+
return internal.create_int_pointer()
63+
64+
def destroy_int_pointer(pointer):
65+
return internal.destroy_int_pointer(pointer)
66+
67+
def create_float_pointer():
68+
return internal.create_float_pointer()
69+
70+
def destroy_float_pointer(pointer):
71+
return internal.destroy_float_pointer(pointer)
72+
6173
class plIOI:
6274

6375
def get_version_string() -> str:

pilotlight/pl_dearimgui_ext.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,50 @@ def cleanup(**kwargs) -> None:
1717

1818
class ImGui:
1919

20+
def StyleColorsDark():
21+
return imgui.plImgui_StyleColorsDark()
22+
23+
def StyleColorsLight():
24+
return imgui.plImgui_StyleColorsLight()
25+
26+
def StyleColorsClassic():
27+
return imgui.plImgui_StyleColorsClassic()
28+
2029
def ShowDemoWindow(bool_pointer = None) -> None:
2130
return imgui.plImGui_ShowDemoWindow(bool_pointer)
2231

23-
def begin(name, bool_pointer = None, flags = imgui.ImGuiWindowFlags_None) -> None:
24-
return imgui.plImgui_begin(name, bool_pointer, flags)
32+
def Begin(name, bool_pointer = None, flags = imgui.ImGuiWindowFlags_None) -> None:
33+
return imgui.plImgui_Begin(name, bool_pointer, flags)
34+
35+
def End():
36+
return imgui.plImgui_End()
37+
38+
def BeginMenuBar():
39+
return imgui.plImgui_BeginMenuBar()
40+
41+
def BeginMainMenuBar():
42+
return imgui.plImgui_BeginMainMenuBar()
2543

26-
def end():
27-
return imgui.plImgui_end()
44+
def EndMenuBar():
45+
return imgui.plImgui_EndMenuBar()
46+
47+
def EndMainMenuBar():
48+
return imgui.plImgui_EndMainMenuBar()
49+
50+
def BeginMenu(label, enabled=True):
51+
return imgui.plImgui_BeginMenu(label, enabled)
52+
53+
def EndMenu():
54+
return imgui.plImgui_EndMenu()
55+
56+
def MenuItem(label, shortcut="", selected=False, enabled=True, selected_pointer = None):
57+
return imgui.plImgui_MenuItem(label, shortcut, selected, enabled, selected_pointer=selected_pointer)
58+
59+
def Button(label, size=None):
60+
return imgui.plImgui_Button(label, size)
61+
62+
def Checkbox(label, bool_pointer):
63+
return imgui.plImgui_Checkbox(label, bool_pointer)
2864

2965
class ImPlot:
3066

sandbox/app.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ def pl_app_load(self):
138138

139139
plRendererI.create_directional_light(self.ptComponentLibrary, "direction light")
140140

141+
ImGui.StyleColorsDark()
142+
141143

142144
def pl_app_shutdown(self):
143145
plGraphicsI.flush_device(plStarterI.get_device())
@@ -198,9 +200,24 @@ def pl_app_update(self):
198200
plUiI.end_window()
199201

200202
# dear imgui API
201-
if ImGui.begin("ImGui Window"):
202-
pass
203-
ImGui.end()
203+
if ImGui.BeginMainMenuBar():
204+
if ImGui.BeginMenu("File"):
205+
ImGui.EndMenu()
206+
if ImGui.BeginMenu("Edit", False):
207+
ImGui.EndMenu()
208+
if ImGui.BeginMenu("Tools"):
209+
ImGui.MenuItem("Show ImGui Demo", selected_pointer=self.show_imgui_demo)
210+
ImGui.MenuItem("Show ImPlot Demo", selected_pointer=self.show_implot_demo)
211+
ImGui.EndMenu()
212+
if ImGui.BeginMenu("Help"):
213+
ImGui.MenuItem("Check For Update")
214+
ImGui.MenuItem("About", "-a")
215+
ImGui.EndMenu()
216+
ImGui.EndMainMenuBar()
217+
if ImGui.Begin("ImGui Window"):
218+
if ImGui.Button("Press Me"):
219+
print("Pressed Imgui Button")
220+
ImGui.End()
204221

205222
render_encoder = plStarterI.begin_main_pass()
206223

src/pilotlight.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,11 @@ static PyMethodDef gatCommands[] =
285285
PL_PYTHON_COMMAND(set_pointer_value, METH_VARARGS, NULL),
286286
PL_PYTHON_COMMAND(get_pointer_value, METH_O, NULL),
287287
PL_PYTHON_COMMAND(create_bool_pointer, METH_NOARGS, NULL),
288+
PL_PYTHON_COMMAND(create_int_pointer, METH_NOARGS, NULL),
289+
PL_PYTHON_COMMAND(create_float_pointer, METH_NOARGS, NULL),
288290
PL_PYTHON_COMMAND(destroy_bool_pointer, METH_O, NULL),
291+
PL_PYTHON_COMMAND(destroy_int_pointer, METH_O, NULL),
292+
PL_PYTHON_COMMAND(destroy_float_pointer, METH_O, NULL),
289293

290294
// window API
291295
PL_PYTHON_COMMAND(plWindowI_create, METH_VARARGS | METH_KEYWORDS, NULL),

0 commit comments

Comments
 (0)