diff --git a/Source/Pd/PdGui.cpp b/Source/Pd/PdGui.cpp index 87672ea7..1b8bc1a6 100755 --- a/Source/Pd/PdGui.cpp +++ b/Source/Pd/PdGui.cpp @@ -28,22 +28,42 @@ namespace pd // False GATOM typedef struct _fake_gatom { - t_text a_text; - t_atom a_atom; - t_glist* a_glist; - t_float a_toggle; - t_float a_draghi; - t_float a_draglo; - t_symbol *a_label; - t_symbol *a_symfrom; - t_symbol *a_symto; - char a_buf[40]; - char a_shift; - char a_wherelabel; // 0-3 for left, right, above, below + t_text a_text; + int a_flavor; /* A_FLOAT, A_SYMBOL, or A_LIST */ + t_glist *a_glist; /* owning glist */ + t_float a_toggle; /* value to toggle to */ + t_float a_draghi; /* high end of drag range */ + t_float a_draglo; /* low end of drag range */ + t_symbol *a_label; /* symbol to show as label next to box */ + t_symbol *a_symfrom; /* "receive" name -- bind ourselves to this */ + t_symbol *a_symto; /* "send" name -- send to this on output */ + t_binbuf *a_revertbuf; /* binbuf to revert to if typing canceled */ + int a_dragindex; /* index of atom being dragged */ + int a_fontsize; + unsigned int a_shift:1; /* was shift key down when drag started? */ + unsigned int a_wherelabel:2; /* 0-3 for left, right, above, below */ + unsigned int a_grabbed:1; /* 1 if we've grabbed keyboard */ + unsigned int a_doubleclicked:1; /* 1 if dragging from a double click */ t_symbol *a_expanded_to; } t_fake_gatom; - + static t_atom *fake_gatom_getatom(t_fake_gatom *x) + { + int ac = binbuf_getnatom(x->a_text.te_binbuf); + t_atom *av = binbuf_getvec(x->a_text.te_binbuf); + if (x->a_flavor == A_FLOAT && (ac != 1 || av[0].a_type != A_FLOAT)) + { + binbuf_clear(x->a_text.te_binbuf); + binbuf_addv(x->a_text.te_binbuf, "f", 0.); + } + else if (x->a_flavor == A_SYMBOL && (ac != 1 || av[0].a_type != A_SYMBOL)) + { + binbuf_clear(x->a_text.te_binbuf); + binbuf_addv(x->a_text.te_binbuf, "s", &s_); + } + return (binbuf_getvec(x->a_text.te_binbuf)); + } + Gui::Gui(void* ptr, void* patch, Instance* instance) noexcept : Object(ptr, patch, instance), m_type(Type::Undefined) { @@ -90,10 +110,12 @@ namespace pd } else if(name == "gatom") { - if(static_cast(m_ptr)->a_atom.a_type == A_FLOAT) + if(static_cast(m_ptr)->a_flavor == A_FLOAT) m_type = Type::AtomNumber; - else if(static_cast(m_ptr)->a_atom.a_type == A_SYMBOL) + else if(static_cast(m_ptr)->a_flavor == A_SYMBOL) m_type = Type::AtomSymbol; + else if(static_cast(m_ptr)->a_flavor == A_NULL) + m_type = Type::AtomList; } else if(name == "canvas") { @@ -250,7 +272,7 @@ namespace pd } else if(m_type == Type::AtomNumber) { - return atom_getfloat(&(static_cast(m_ptr)->a_atom)); + return atom_getfloat(fake_gatom_getatom(static_cast(m_ptr))); } return 0.f; } @@ -299,7 +321,7 @@ namespace pd else { m_instance->setThis(); - return atom_getsymbol(&(static_cast(m_ptr)->a_atom))->s_name; + return atom_getsymbol(fake_gatom_getatom(static_cast(m_ptr)))->s_name; } } @@ -310,6 +332,44 @@ namespace pd m_instance->enqueueDirectMessages(m_ptr, value); } + std::vector Gui::getList() const noexcept + { + if(!m_ptr || m_type != Type::AtomList) + return {}; + else + { + std::vector array; + m_instance->setThis(); + + int ac = binbuf_getnatom(static_cast(m_ptr)->a_text.te_binbuf); + t_atom *av = binbuf_getvec(static_cast(m_ptr)->a_text.te_binbuf); + array.reserve(ac); + for(int i = 0; i < ac; ++i) + { + if(av[i].a_type == A_FLOAT) + { + array.push_back({atom_getfloat(av+i)}); + } + else if(av[i].a_type == A_SYMBOL) + { + array.push_back({atom_getsymbol(av+i)->s_name}); + } + else + { + array.push_back({}); + } + } + return array; + } + } + + void Gui::setList(std::vector const& value) noexcept + { + if(!m_ptr || m_type != Type::AtomList) + return; + m_instance->enqueueDirectMessages(m_ptr, value); + } + float Gui::getFontHeight() const noexcept { if(!m_ptr ) @@ -371,7 +431,7 @@ namespace pd static_cast(m_ptr)->x_vis_w + 1, static_cast(m_ptr)->x_vis_h + 1}; } - else if(m_type == Type::AtomNumber || m_type == Type::AtomSymbol) + else if(m_type == Type::AtomNumber || m_type == Type::AtomSymbol || m_type == Type::AtomList) { std::array const bounds = Object::getBounds(); return {bounds[0], bounds[1], bounds[2], bounds[3] - 2}; diff --git a/Source/Pd/PdGui.hpp b/Source/Pd/PdGui.hpp index 90ba5a68..6f00d62b 100755 --- a/Source/Pd/PdGui.hpp +++ b/Source/Pd/PdGui.hpp @@ -7,6 +7,7 @@ #include "PdObject.hpp" #include "PdArray.hpp" +#include "PdAtom.hpp" namespace pd { @@ -39,8 +40,9 @@ namespace pd Comment = 10, AtomNumber = 11, AtomSymbol = 12, - Array = 13, - GraphOnParent = 14 + AtomList = 13, + Array = 14, + GraphOnParent = 15 }; //! @brief The default constructor @@ -70,7 +72,7 @@ namespace pd //! @brief If the GUI is an Atom GUI (AtomNumber or AtomSymbol). bool isAtom() const noexcept { - return (m_type == Type::AtomNumber) || (m_type == Type::AtomSymbol); + return (m_type == Type::AtomNumber) || (m_type == Type::AtomSymbol) || (m_type == Type::AtomList); } //! @brief Get the font height. @@ -97,6 +99,10 @@ namespace pd void setSymbol(std::string const& value) noexcept; + std::vector getList() const noexcept; + + void setList(std::vector const& value) noexcept; + std::array getBounds() const noexcept override; bool jumpOnClick() const noexcept;