11 #include <type_traits>
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)))
39 if (!isMainMenu) { XPLMDestroyMenu(
id); }
42 CMenu CMenu::mainMenu() {
return { XPLMFindPluginsMenu(),
true,
nullptr }; }
44 CMenuItem CMenu::item(
const std::string &name, std::function<
void()> callback)
46 assert(!name.empty());
47 m_data->items->emplace_back(CMenuItem { m_data->id, 0,
false, [callback](bool) { callback(); } });
48 auto &menuItem = m_data->items->back();
49 menuItem.setIndex(XPLMAppendMenuItem(m_data->id, name.c_str(), &menuItem,
false));
53 CMenuItem CMenu::checkableItem(
const std::string &name,
bool checked, std::function<
void(
bool)> callback)
55 assert(!name.empty());
56 m_data->items->emplace_back(CMenuItem { m_data->id, 0,
true, callback });
57 auto &menuItem = m_data->items->back();
58 menuItem.setIndex(XPLMAppendMenuItem(m_data->id, name.c_str(), &menuItem,
false));
59 menuItem.setChecked(checked);
63 void CMenu::removeItem(
const CMenuItem &item)
65 auto it = std::find_if(m_data->items->begin(), m_data->items->end(),
66 [=](
const auto &i) { return i.m_data->index == item.m_data->index; });
68 XPLMRemoveMenuItem(m_data->id, it->m_data->index);
69 it = m_data->items->erase(it);
72 while (it != m_data->items->end())
79 void CMenu::sep() { XPLMAppendMenuSeparator(m_data->id); }
81 CMenu CMenu::subMenu(
const std::string &name)
83 assert(!name.empty());
85 auto items = std::make_unique<ItemList>();
86 auto itemsVoidPtr =
static_cast<void *
>(&*items);
87 return { XPLMCreateMenu(name.c_str(), m_data->id, XPLMAppendMenuItem(m_data->id, name.c_str(),
nullptr,
false),
88 handler, itemsVoidPtr),
89 false, std::move(items) };
93 void CMenu::handler(
void *menuRef,
void *itemRef)
95 if (menuRef && itemRef)
97 CMenuItem *menuItem =
static_cast<CMenuItem *
>(itemRef);
98 menuItem->m_data->callback(menuItem->getChecked());
102 CMenuItem::CMenuItem(XPLMMenuID parent,
int item,
bool checkable, std::function<
void(
bool)> callback)
103 : m_data(std::make_shared<Data>(parent, item, checkable, callback))
106 bool CMenuItem::getChecked()
const
108 XPLMMenuCheck check = xplm_Menu_NoCheck;
109 XPLMCheckMenuItemState(m_data->parent, m_data->index, &check);
110 return check == xplm_Menu_Checked;
113 void CMenuItem::setChecked(
bool checked)
115 XPLMCheckMenuItem(m_data->parent, m_data->index, checked ? xplm_Menu_Checked : xplm_Menu_Unchecked);
118 void CMenuItem::setEnabled(
bool enabled) { XPLMEnableMenuItem(m_data->parent, m_data->index, enabled); }
Plugin loaded by X-Plane which publishes a DBus service.