17 void *voidptr_cast(T i)
19 static_assert(std::is_integral_v<T>,
"voidptr_cast expects an integer");
20 using intptr_type = std::conditional_t<std::is_signed_v<T>, intptr_t, uintptr_t>;
21 return reinterpret_cast<void *
>(
static_cast<intptr_type
>(i));
26 T intptr_cast(
void *p)
28 static_assert(std::is_integral<T>::value,
"voidptr_cast returns an integer");
29 using intptr_type = std::conditional_t<std::is_signed_v<T>, intptr_t, uintptr_t>;
30 return static_cast<T
>(
reinterpret_cast<intptr_type
>(p));
33 CMenu::CMenu(XPLMMenuID
id,
bool isMainMenu, std::unique_ptr<ItemList> items)
34 : m_data(std::make_shared<Data>(id, isMainMenu, std::move(items)))
45 CMenu CMenu::mainMenu() {
return { XPLMFindPluginsMenu(),
true,
nullptr }; }
47 CMenuItem CMenu::appendItem(
const std::string &name, std::function<
void()> callback)
49 assert(!name.empty());
50 m_data->items->emplace_back(CMenuItem { m_data->id, 0,
false, [callback](bool) { callback(); } });
51 auto &menuItem = m_data->items->back();
52 menuItem.setIndex(XPLMAppendMenuItem(m_data->id, name.c_str(), &menuItem,
false));
56 CMenuItem CMenu::checkableItem(
const std::string &name,
bool checked, std::function<
void(
bool)> callback)
58 assert(!name.empty());
59 m_data->items->emplace_back(CMenuItem { m_data->id, 0,
true, callback });
60 auto &menuItem = m_data->items->back();
61 menuItem.setIndex(XPLMAppendMenuItem(m_data->id, name.c_str(), &menuItem,
false));
62 menuItem.setChecked(checked);
66 void CMenu::removeItem(
const CMenuItem &item)
68 auto it = std::find_if(m_data->items->begin(), m_data->items->end(),
69 [=](
const auto &i) { return i.m_data->index == item.m_data->index; });
71 XPLMRemoveMenuItem(m_data->id, it->m_data->index);
72 it = m_data->items->erase(it);
75 while (it != m_data->items->end())
82 void CMenu::sep() { XPLMAppendMenuSeparator(m_data->id); }
84 CMenu CMenu::subMenu(
const std::string &name)
86 assert(!name.empty());
88 auto items = std::make_unique<ItemList>();
89 auto itemsVoidPtr =
static_cast<void *
>(&*items);
90 return { XPLMCreateMenu(name.c_str(), m_data->id, XPLMAppendMenuItem(m_data->id, name.c_str(),
nullptr,
false),
91 handler, itemsVoidPtr),
92 false, std::move(items) };
96 void CMenu::handler(
void *menuRef,
void *itemRef)
98 if (menuRef && itemRef)
100 CMenuItem *menuItem =
static_cast<CMenuItem *
>(itemRef);
101 menuItem->m_data->callback(menuItem->getChecked());
105 CMenuItem::CMenuItem(XPLMMenuID parent,
int item,
bool checkable, std::function<
void(
bool)> callback)
106 : m_data(std::make_shared<Data>(parent, item, checkable, callback))
109 bool CMenuItem::getChecked()
const
111 XPLMMenuCheck check = xplm_Menu_NoCheck;
112 XPLMCheckMenuItemState(m_data->parent, m_data->index, &check);
113 return check == xplm_Menu_Checked;
116 void CMenuItem::setChecked(
bool checked)
118 XPLMCheckMenuItem(m_data->parent, m_data->index, checked ? xplm_Menu_Checked : xplm_Menu_Unchecked);
121 void CMenuItem::setEnabled(
bool enabled) { XPLMEnableMenuItem(m_data->parent, m_data->index, enabled); }
Plugin loaded by X-Plane which publishes a DBus service.