summaryrefslogtreecommitdiffhomepage
path: root/X-Plane-SDK/CHeaders/Wrappers
diff options
context:
space:
mode:
Diffstat (limited to 'X-Plane-SDK/CHeaders/Wrappers')
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCBroadcaster.cpp56
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCBroadcaster.h38
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCDisplay.cpp104
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCDisplay.h73
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCListener.cpp27
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCListener.h36
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCProcessing.cpp52
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCProcessing.h37
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCWidget.cpp123
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCWidget.h84
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCWidgetAttachments.cpp267
-rwxr-xr-xX-Plane-SDK/CHeaders/Wrappers/XPCWidgetAttachments.h146
12 files changed, 1043 insertions, 0 deletions
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCBroadcaster.cpp b/X-Plane-SDK/CHeaders/Wrappers/XPCBroadcaster.cpp
new file mode 100755
index 0000000..5fe6218
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCBroadcaster.cpp
@@ -0,0 +1,56 @@
+#include "XPCBroadcaster.h"
+#include "XPCListener.h"
+
+XPCBroadcaster::XPCBroadcaster() :
+ mIterator(NULL)
+{
+}
+
+XPCBroadcaster::~XPCBroadcaster()
+{
+ ListenerVector::iterator iter;
+ mIterator = &iter;
+ for (iter = mListeners.begin(); iter != mListeners.end(); ++iter)
+ {
+ (*iter)->BroadcasterRemoved(this);
+ }
+}
+
+void XPCBroadcaster::AddListener(
+ XPCListener * inListener)
+{
+ mListeners.push_back(inListener);
+ inListener->BroadcasterAdded(this);
+}
+
+void XPCBroadcaster::RemoveListener(
+ XPCListener * inListener)
+{
+ ListenerVector::iterator iter = std::find
+ (mListeners.begin(), mListeners.end(), inListener);
+ if (iter == mListeners.end())
+ return;
+
+ if (mIterator != NULL)
+ {
+ if (*mIterator >= iter)
+ (*mIterator)--;
+ }
+
+ mListeners.erase(iter);
+ inListener->BroadcasterRemoved(this);
+}
+
+void XPCBroadcaster::BroadcastMessage(
+ int inMessage,
+ void * inParam)
+{
+ ListenerVector::iterator iter;
+ mIterator = &iter;
+ for (iter = mListeners.begin(); iter != mListeners.end(); ++iter)
+ {
+ (*iter)->ListenToMessage(inMessage, inParam);
+ }
+ mIterator = NULL;
+}
+
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCBroadcaster.h b/X-Plane-SDK/CHeaders/Wrappers/XPCBroadcaster.h
new file mode 100755
index 0000000..8f34a05
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCBroadcaster.h
@@ -0,0 +1,38 @@
+#ifndef _XPCBroadcaster_h_
+#define _XPCBroadcaster_h_
+
+#include <vector>
+#include <algorithm>
+
+class XPCListener;
+
+class XPCBroadcaster {
+public:
+
+ XPCBroadcaster();
+ virtual ~XPCBroadcaster();
+
+ void AddListener(
+ XPCListener * inListener);
+ void RemoveListener(
+ XPCListener * inListener);
+
+protected:
+
+ void BroadcastMessage(
+ int inMessage,
+ void * inParam=0);
+
+private:
+
+ typedef std::vector<XPCListener *> ListenerVector;
+
+ ListenerVector mListeners;
+
+ // Reentrancy support
+
+ ListenerVector::iterator * mIterator;
+
+};
+
+#endif \ No newline at end of file
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCDisplay.cpp b/X-Plane-SDK/CHeaders/Wrappers/XPCDisplay.cpp
new file mode 100755
index 0000000..fc996ca
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCDisplay.cpp
@@ -0,0 +1,104 @@
+#include "XPCDisplay.h"
+
+XPCKeySniffer::XPCKeySniffer(int inBeforeWindows) : mBeforeWindows(inBeforeWindows)
+{
+ XPLMRegisterKeySniffer(KeySnifferCB, mBeforeWindows, reinterpret_cast<void *>(this));
+}
+
+XPCKeySniffer::~XPCKeySniffer()
+{
+ XPLMUnregisterKeySniffer(KeySnifferCB, mBeforeWindows, reinterpret_cast<void *>(this));
+}
+
+
+int XPCKeySniffer::KeySnifferCB(
+ char inCharKey,
+ XPLMKeyFlags inFlags,
+ char inVirtualKey,
+ void * inRefCon)
+{
+ XPCKeySniffer * me = reinterpret_cast<XPCKeySniffer *>(inRefCon);
+ return me->HandleKeyStroke(inCharKey, inFlags, inVirtualKey);
+}
+
+XPCWindow::XPCWindow(
+ int inLeft,
+ int inTop,
+ int inRight,
+ int inBottom,
+ int inIsVisible)
+{
+ mWindow = XPLMCreateWindow(inLeft, inTop, inRight, inBottom, inIsVisible,
+ DrawCB, HandleKeyCB, MouseClickCB,
+ reinterpret_cast<void *>(this));
+}
+
+XPCWindow::~XPCWindow()
+{
+ XPLMDestroyWindow(mWindow);
+}
+
+void XPCWindow::GetWindowGeometry(
+ int * outLeft,
+ int * outTop,
+ int * outRight,
+ int * outBottom)
+{
+ XPLMGetWindowGeometry(mWindow, outLeft, outTop, outRight, outBottom);
+}
+
+void XPCWindow::SetWindowGeometry(
+ int inLeft,
+ int inTop,
+ int inRight,
+ int inBottom)
+{
+ XPLMSetWindowGeometry(mWindow, inLeft, inTop, inRight, inBottom);
+}
+
+int XPCWindow::GetWindowIsVisible(void)
+{
+ return XPLMGetWindowIsVisible(mWindow);
+}
+
+void XPCWindow::SetWindowIsVisible(
+ int inIsVisible)
+{
+ XPLMSetWindowIsVisible(mWindow, inIsVisible);
+}
+
+void XPCWindow::TakeKeyboardFocus(void)
+{
+ XPLMTakeKeyboardFocus(mWindow);
+}
+
+void XPCWindow::BringWindowToFront(void)
+{
+ XPLMBringWindowToFront(mWindow);
+}
+
+int XPCWindow::IsWindowInFront(void)
+{
+ return XPLMIsWindowInFront(mWindow);
+}
+
+void XPCWindow::DrawCB(XPLMWindowID inWindowID, void * inRefcon)
+{
+ XPCWindow * me = reinterpret_cast<XPCWindow *>(inRefcon);
+ me->DoDraw();
+}
+
+void XPCWindow::HandleKeyCB(XPLMWindowID inWindowID, char inKey, XPLMKeyFlags inFlags, char inVirtualKey, void * inRefcon, int losingFocus)
+{
+ XPCWindow * me = reinterpret_cast<XPCWindow *>(inRefcon);
+ if (losingFocus)
+ me->LoseFocus();
+ else
+ me->HandleKey(inKey, inFlags, inVirtualKey);
+}
+
+int XPCWindow::MouseClickCB(XPLMWindowID inWindowID, int x, int y, XPLMMouseStatus inMouse, void * inRefcon)
+{
+ XPCWindow * me = reinterpret_cast<XPCWindow *>(inRefcon);
+ return me->HandleClick(x, y, inMouse);
+}
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCDisplay.h b/X-Plane-SDK/CHeaders/Wrappers/XPCDisplay.h
new file mode 100755
index 0000000..2465928
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCDisplay.h
@@ -0,0 +1,73 @@
+#ifndef _XPCDisplay_h_
+#define _XPCDisplay_h_
+
+#include "XPLMDisplay.h"
+
+class XPCKeySniffer {
+public:
+
+ XPCKeySniffer(int inBeforeWindows);
+ virtual ~XPCKeySniffer();
+
+ virtual int HandleKeyStroke(
+ char inCharKey,
+ XPLMKeyFlags inFlags,
+ char inVirtualKey)=0;
+
+private:
+
+ int mBeforeWindows;
+
+ static int KeySnifferCB(
+ char inCharKey,
+ XPLMKeyFlags inFlags,
+ char inVirtualKey,
+ void * inRefCon);
+};
+
+
+
+class XPCWindow {
+public:
+
+ XPCWindow(
+ int inLeft,
+ int inTop,
+ int inRight,
+ int inBottom,
+ int inIsVisible);
+ virtual ~XPCWindow();
+
+ virtual void DoDraw(void)=0;
+ virtual void HandleKey(char inKey, XPLMKeyFlags inFlags, char inVirtualKey)=0;
+ virtual void LoseFocus(void)=0;
+ virtual int HandleClick(int x, int y, XPLMMouseStatus inMouse)=0;
+
+ void GetWindowGeometry(
+ int * outLeft,
+ int * outTop,
+ int * outRight,
+ int * outBottom);
+ void SetWindowGeometry(
+ int inLeft,
+ int inTop,
+ int inRight,
+ int inBottom);
+ int GetWindowIsVisible(void);
+ void SetWindowIsVisible(
+ int inIsVisible);
+ void TakeKeyboardFocus(void);
+ void BringWindowToFront(void);
+ int IsWindowInFront(void);
+
+private:
+
+ XPLMWindowID mWindow;
+
+ static void DrawCB(XPLMWindowID inWindowID, void * inRefcon);
+ static void HandleKeyCB(XPLMWindowID inWindowID, char inKey, XPLMKeyFlags inFlags, char inVirtualKey, void * inRefcon, int losingFocus);
+ static int MouseClickCB(XPLMWindowID inWindowID, int x, int y, XPLMMouseStatus inMouse, void * inRefcon);
+
+};
+
+#endif \ No newline at end of file
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCListener.cpp b/X-Plane-SDK/CHeaders/Wrappers/XPCListener.cpp
new file mode 100755
index 0000000..b4c77aa
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCListener.cpp
@@ -0,0 +1,27 @@
+#include "XPCListener.h"
+#include "XPCBroadcaster.h"
+
+XPCListener::XPCListener()
+{
+}
+
+XPCListener::~XPCListener()
+{
+ while (!mBroadcasters.empty())
+ mBroadcasters.front()->RemoveListener(this);
+}
+
+void XPCListener::BroadcasterAdded(
+ XPCBroadcaster * inBroadcaster)
+{
+ mBroadcasters.push_back(inBroadcaster);
+}
+
+void XPCListener::BroadcasterRemoved(
+ XPCBroadcaster * inBroadcaster)
+{
+ BroadcastVector::iterator iter = std::find(mBroadcasters.begin(),
+ mBroadcasters.end(), inBroadcaster);
+ if (iter != mBroadcasters.end())
+ mBroadcasters.erase(iter);
+}
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCListener.h b/X-Plane-SDK/CHeaders/Wrappers/XPCListener.h
new file mode 100755
index 0000000..dbdd2a0
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCListener.h
@@ -0,0 +1,36 @@
+#ifndef _XPCListener_h_
+#define _XPCListener_h_
+
+#include <vector>
+#include <algorithm>
+
+class XPCBroadcaster;
+
+
+class XPCListener {
+public:
+
+ XPCListener();
+ virtual ~XPCListener();
+
+ virtual void ListenToMessage(
+ int inMessage,
+ void * inParam)=0;
+
+private:
+
+ typedef std::vector<XPCBroadcaster *> BroadcastVector;
+
+ BroadcastVector mBroadcasters;
+
+ friend class XPCBroadcaster;
+
+ void BroadcasterAdded(
+ XPCBroadcaster * inBroadcaster);
+
+ void BroadcasterRemoved(
+ XPCBroadcaster * inBroadcaster);
+
+};
+
+#endif \ No newline at end of file
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCProcessing.cpp b/X-Plane-SDK/CHeaders/Wrappers/XPCProcessing.cpp
new file mode 100755
index 0000000..352c05f
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCProcessing.cpp
@@ -0,0 +1,52 @@
+#include "XPCProcessing.h"
+#include "XPLMUtilities.h"
+
+XPCProcess::XPCProcess() :
+ mInCallback(false),
+ mCallbackTime(0)
+{
+ XPLMRegisterFlightLoopCallback(FlightLoopCB, 0, reinterpret_cast<void *>(this));
+}
+
+XPCProcess::~XPCProcess()
+{
+ XPLMUnregisterFlightLoopCallback(FlightLoopCB, reinterpret_cast<void *>(this));
+}
+
+void XPCProcess::StartProcessTime(float inSeconds)
+{
+ mCallbackTime = inSeconds;
+ if (!mInCallback)
+ XPLMSetFlightLoopCallbackInterval(
+ FlightLoopCB, mCallbackTime, 1/*relative to now*/, reinterpret_cast<void *>(this));
+}
+
+void XPCProcess::StartProcessCycles(int inCycles)
+{
+ mCallbackTime = -inCycles;
+ if (!mInCallback)
+ XPLMSetFlightLoopCallbackInterval(
+ FlightLoopCB, mCallbackTime, 1/*relative to now*/, reinterpret_cast<void *>(this));
+}
+
+void XPCProcess::StopProcess(void)
+{
+ mCallbackTime = 0;
+ if (!mInCallback)
+ XPLMSetFlightLoopCallbackInterval(
+ FlightLoopCB, mCallbackTime, 1/*relative to now*/, reinterpret_cast<void *>(this));
+}
+
+
+float XPCProcess::FlightLoopCB(
+ float inElapsedSinceLastCall,
+ float inElapsedTimeSinceLastFlightLoop,
+ int inCounter,
+ void * inRefcon)
+{
+ XPCProcess * me = reinterpret_cast<XPCProcess *>(inRefcon);
+ me->mInCallback = true;
+ me->DoProcessing(inElapsedSinceLastCall, inElapsedTimeSinceLastFlightLoop, inCounter);
+ me->mInCallback = false;
+ return me->mCallbackTime;
+} \ No newline at end of file
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCProcessing.h b/X-Plane-SDK/CHeaders/Wrappers/XPCProcessing.h
new file mode 100755
index 0000000..cd735e5
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCProcessing.h
@@ -0,0 +1,37 @@
+#ifndef _XPCProcessing_h_
+#define _XPCProcessing_h_
+
+#include "XPLMProcessing.h"
+
+class XPCProcess {
+public:
+
+ XPCProcess();
+ virtual ~XPCProcess();
+
+ void StartProcessTime(float inSeconds);
+ void StartProcessCycles(int inCycles);
+ void StopProcess(void);
+
+ virtual void DoProcessing(
+ float inElapsedSinceLastCall,
+ float inElapsedTimeSinceLastFlightLoop,
+ int inCounter)=0;
+
+private:
+
+ static float FlightLoopCB(
+ float inElapsedSinceLastCall,
+ float inElapsedTimeSinceLastFlightLoop,
+ int inCounter,
+ void * inRefcon);
+
+ bool mInCallback;
+ float mCallbackTime;
+
+ XPCProcess(const XPCProcess&);
+ XPCProcess& operator=(const XPCProcess&);
+
+};
+
+#endif
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCWidget.cpp b/X-Plane-SDK/CHeaders/Wrappers/XPCWidget.cpp
new file mode 100755
index 0000000..8ef8aa3
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCWidget.cpp
@@ -0,0 +1,123 @@
+#include "XPCWidget.h"
+
+XPCWidget::XPCWidget(
+ int inLeft,
+ int inTop,
+ int inRight,
+ int inBottom,
+ bool inVisible,
+ const char * inDescriptor,
+ bool inIsRoot,
+ XPWidgetID inParent,
+ XPWidgetClass inClass) :
+ mWidget(NULL),
+ mOwnsChildren(false),
+ mOwnsWidget(true)
+{
+ mWidget = XPCreateWidget(
+ inLeft, inTop, inRight, inBottom,
+ inVisible ? 1 : 0,
+ inDescriptor,
+ inIsRoot ? 1 : 0,
+ inIsRoot ? NULL : inParent,
+ inClass);
+
+ XPSetWidgetProperty(mWidget, xpProperty_Object, reinterpret_cast<intptr_t>(this));
+ XPAddWidgetCallback(mWidget, WidgetCallback);
+}
+
+XPCWidget::XPCWidget(
+ XPWidgetID inWidget,
+ bool inOwnsWidget) :
+ mWidget(inWidget),
+ mOwnsChildren(false),
+ mOwnsWidget(inOwnsWidget)
+{
+ XPSetWidgetProperty(mWidget, xpProperty_Object, reinterpret_cast<intptr_t>(this));
+ XPAddWidgetCallback(mWidget, WidgetCallback);
+}
+
+XPCWidget::~XPCWidget()
+{
+ if (mOwnsWidget)
+ XPDestroyWidget(mWidget, mOwnsChildren ? 1 : 0);
+}
+
+void XPCWidget::SetOwnsWidget(
+ bool inOwnsWidget)
+{
+ mOwnsWidget = inOwnsWidget;
+}
+
+void XPCWidget::SetOwnsChildren(
+ bool inOwnsChildren)
+{
+ mOwnsChildren = inOwnsChildren;
+}
+
+XPCWidget::operator XPWidgetID () const
+{
+ return mWidget;
+}
+
+XPWidgetID XPCWidget::Get(void) const
+{
+ return mWidget;
+}
+
+void XPCWidget::AddAttachment(
+ XPCWidgetAttachment * inAttachment,
+ bool inOwnsAttachment,
+ bool inPrefilter)
+{
+ if (inPrefilter)
+ {
+ mAttachments.insert(mAttachments.begin(), AttachmentInfo(inAttachment, inOwnsAttachment));
+ } else {
+ mAttachments.push_back(AttachmentInfo(inAttachment, inOwnsAttachment));
+ }
+}
+
+void XPCWidget::RemoveAttachment(
+ XPCWidgetAttachment * inAttachment)
+{
+ for (AttachmentVector::iterator iter = mAttachments.begin();
+ iter != mAttachments.end(); ++iter)
+ {
+ if (iter->first == inAttachment)
+ {
+ mAttachments.erase(iter);
+ return;
+ }
+ }
+}
+
+int XPCWidget::HandleWidgetMessage(
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)
+{
+ return 0;
+}
+
+int XPCWidget::WidgetCallback(
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)
+{
+ XPCWidget * me = reinterpret_cast<XPCWidget *>(XPGetWidgetProperty(inWidget, xpProperty_Object, NULL));
+ if (me == NULL)
+ return 0;
+
+ for (AttachmentVector::iterator iter = me->mAttachments.begin(); iter !=
+ me->mAttachments.end(); ++iter)
+ {
+ int result = iter->first->HandleWidgetMessage(me, inMessage, inWidget, inParam1, inParam2);
+ if (result != 0)
+ return result;
+ }
+
+ return me->HandleWidgetMessage(inMessage, inWidget, inParam1, inParam2);
+}
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCWidget.h b/X-Plane-SDK/CHeaders/Wrappers/XPCWidget.h
new file mode 100755
index 0000000..788b56a
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCWidget.h
@@ -0,0 +1,84 @@
+#ifndef _XPCWidget_h_
+#define _XPCWidget_h_
+
+#include <vector>
+#include <algorithm>
+#include "XPWidgets.h"
+
+class XPCWidget;
+
+class XPCWidgetAttachment {
+public:
+
+ virtual int HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)=0;
+
+};
+
+class XPCWidget {
+public:
+
+ XPCWidget(
+ int inLeft,
+ int inTop,
+ int inRight,
+ int inBottom,
+ bool inVisible,
+ const char * inDescriptor,
+ bool inIsRoot,
+ XPWidgetID inParent,
+ XPWidgetClass inClass);
+ XPCWidget(
+ XPWidgetID inWidget,
+ bool inOwnsWidget);
+ virtual ~XPCWidget();
+
+ void SetOwnsWidget(
+ bool inOwnsWidget);
+ void SetOwnsChildren(
+ bool inOwnsChildren);
+
+ operator XPWidgetID () const;
+
+ XPWidgetID Get(void) const;
+
+ void AddAttachment(
+ XPCWidgetAttachment * inAttachment,
+ bool inOwnsAttachment,
+ bool inPrefilter);
+ void RemoveAttachment(
+ XPCWidgetAttachment * inAttachment);
+
+ virtual int HandleWidgetMessage(
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2);
+
+private:
+
+ static int WidgetCallback(
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2);
+
+ typedef std::pair<XPCWidgetAttachment *, bool> AttachmentInfo;
+ typedef std::vector<AttachmentInfo> AttachmentVector;
+
+ AttachmentVector mAttachments;
+ XPWidgetID mWidget;
+ bool mOwnsChildren;
+ bool mOwnsWidget;
+
+ XPCWidget();
+ XPCWidget(const XPCWidget&);
+ XPCWidget& operator=(const XPCWidget&);
+
+};
+
+#endif \ No newline at end of file
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCWidgetAttachments.cpp b/X-Plane-SDK/CHeaders/Wrappers/XPCWidgetAttachments.cpp
new file mode 100755
index 0000000..d87f105
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCWidgetAttachments.cpp
@@ -0,0 +1,267 @@
+#include "XPCWidgetAttachments.h"
+#include "XPStandardWidgets.h"
+#include "XPWidgetUtils.h"
+
+static void XPCGetOrderedSubWidgets(
+ XPWidgetID inWidget,
+ std::vector<XPWidgetID>& outChildren);
+
+XPCKeyFilterAttachment::XPCKeyFilterAttachment(
+ const char * inValidKeys,
+ const char * outValidKeys) :
+ mInput(inValidKeys),
+ mOutput(outValidKeys)
+{
+}
+
+XPCKeyFilterAttachment::~XPCKeyFilterAttachment()
+{
+}
+
+int XPCKeyFilterAttachment::HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)
+{
+ if (inMessage == xpMsg_KeyPress)
+ {
+ char& theKey = KEY_CHAR(inParam1);
+ std::string::size_type pos = mInput.find(theKey);
+ if (pos == std::string::npos)
+ return 1; // Not found; eat the key!
+ else {
+ theKey = mOutput[pos];
+ return 0;
+ } // Let it live.
+ }
+ return 0;
+}
+
+
+XPCKeyMessageAttachment::XPCKeyMessageAttachment(
+ char inKey,
+ int inMessage,
+ void * inParam,
+ bool inConsume,
+ bool inVkey,
+ XPCListener * inListener) :
+ mKey(inKey), mMsg(inMessage), mParam(inParam), mConsume(inConsume),
+ mVkey(inVkey)
+{
+ if (inListener != NULL)
+ this->AddListener(inListener);
+}
+
+XPCKeyMessageAttachment::~XPCKeyMessageAttachment()
+{
+}
+
+int XPCKeyMessageAttachment::HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)
+{
+ if (inMessage == xpMsg_KeyPress)
+ {
+ char theKey = mVkey ? KEY_VKEY(inParam1) : KEY_CHAR(inParam1);
+ if (theKey != mKey)
+ return 0;
+ if (!(KEY_FLAGS(inParam1) & xplm_DownFlag))
+ return 0;
+
+ BroadcastMessage(mMsg, mParam);
+ return mConsume ? 1 : 0;
+ }
+ return 0;
+}
+
+XPCPushButtonMessageAttachment::XPCPushButtonMessageAttachment(
+ XPWidgetID inWidget,
+ int inMessage,
+ void * inParam,
+ XPCListener * inListener) :
+ mMsg(inMessage), mParam(inParam), mWidget(inWidget)
+{
+ if (inListener != NULL)
+ this->AddListener(inListener);
+}
+
+XPCPushButtonMessageAttachment::~XPCPushButtonMessageAttachment()
+{
+}
+
+int XPCPushButtonMessageAttachment::HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)
+{
+ if ((inMessage == xpMsg_PushButtonPressed) && ((XPWidgetID) inParam1 == mWidget))
+ {
+ BroadcastMessage(mMsg, mParam);
+ return 1;
+ }
+
+ if ((inMessage == xpMsg_ButtonStateChanged) && ((XPWidgetID) inParam1 == mWidget))
+ {
+ BroadcastMessage(mMsg, mParam);
+ return 1;
+ }
+ return 0;
+}
+
+XPCSliderMessageAttachment::XPCSliderMessageAttachment(
+ XPWidgetID inWidget,
+ int inMessage,
+ void * inParam,
+ XPCListener * inListener) :
+ mMsg(inMessage), mParam(inParam), mWidget(inWidget)
+{
+ if (inListener != NULL)
+ this->AddListener(inListener);
+}
+
+XPCSliderMessageAttachment::~XPCSliderMessageAttachment()
+{
+}
+
+int XPCSliderMessageAttachment::HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)
+{
+ if ((inMessage == xpMsg_ScrollBarSliderPositionChanged) && ((XPWidgetID) inParam1 == mWidget))
+ {
+ BroadcastMessage(mMsg, mParam);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+XPCCloseButtonMessageAttachment::XPCCloseButtonMessageAttachment(
+ XPWidgetID inWidget,
+ int inMessage,
+ void * inParam,
+ XPCListener * inListener) :
+ mMsg(inMessage), mParam(inParam), mWidget(inWidget)
+{
+ if (inListener != NULL)
+ this->AddListener(inListener);
+}
+
+XPCCloseButtonMessageAttachment::~XPCCloseButtonMessageAttachment()
+{
+}
+
+int XPCCloseButtonMessageAttachment::HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)
+{
+ if ((inMessage == xpMessage_CloseButtonPushed) && ((XPWidgetID) inParam1 == mWidget))
+ {
+ BroadcastMessage(mMsg, mParam);
+ return 1;
+ }
+
+ return 0;
+}
+
+XPCTabGroupAttachment::XPCTabGroupAttachment()
+{
+}
+
+XPCTabGroupAttachment::~XPCTabGroupAttachment()
+{
+}
+
+int XPCTabGroupAttachment::HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2)
+{
+ if ((inMessage == xpMsg_KeyPress) && (KEY_CHAR(inParam1) == XPLM_KEY_TAB) &&
+ ((KEY_FLAGS(inParam1) & xplm_UpFlag) == 0))
+ {
+ bool backwards = (KEY_FLAGS(inParam1) & xplm_ShiftFlag) != 0;
+ std::vector<XPWidgetID> widgets;
+ XPCGetOrderedSubWidgets(inWidget, widgets);
+ int n, index = 0;
+ XPWidgetID focusWidget = XPGetWidgetWithFocus();
+ std::vector<XPWidgetID>::iterator iter = std::find(widgets.begin(), widgets.end(), focusWidget);
+ if (iter != widgets.end())
+ {
+ index = std::distance(widgets.begin(), iter);
+ if (backwards)
+ index--;
+ else
+ index++;
+ if (index < 0)
+ index = widgets.size() - 1;
+ if (index >= widgets.size())
+ index = 0;
+ }
+
+ if (backwards)
+ {
+ for (n = index; n >= 0; --n)
+ {
+ if (XPGetWidgetProperty(widgets[n], xpProperty_Enabled, NULL))
+ if (XPSetKeyboardFocus(widgets[n]) != NULL)
+ return 1;
+ }
+ for (n = widgets.size() - 1; n > index; --n)
+ {
+ if (XPGetWidgetProperty(widgets[n], xpProperty_Enabled, NULL))
+ if (XPSetKeyboardFocus(widgets[n]) != NULL)
+ return 1;
+ }
+ } else {
+ for (n = index; n < widgets.size(); ++n)
+ {
+ if (XPGetWidgetProperty(widgets[n], xpProperty_Enabled, NULL))
+ if (XPSetKeyboardFocus(widgets[n]) != NULL)
+ return 1;
+ }
+ for (n = 0; n < index; ++n)
+ {
+ if (XPGetWidgetProperty(widgets[n], xpProperty_Enabled, NULL))
+ if (XPSetKeyboardFocus(widgets[n]) != NULL)
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+
+static void XPCGetOrderedSubWidgets(
+ XPWidgetID inWidget,
+ std::vector<XPWidgetID>& outChildren)
+{
+ outChildren.clear();
+ int count = XPCountChildWidgets(inWidget);
+ for (int n = 0; n < count; ++n)
+ {
+ XPWidgetID child = XPGetNthChildWidget(inWidget, n);
+ outChildren.push_back(child);
+ std::vector<XPWidgetID> grandChildren;
+ XPCGetOrderedSubWidgets(child, grandChildren);
+
+ outChildren.insert(outChildren.end(), grandChildren.begin(), grandChildren.end());
+ }
+}
diff --git a/X-Plane-SDK/CHeaders/Wrappers/XPCWidgetAttachments.h b/X-Plane-SDK/CHeaders/Wrappers/XPCWidgetAttachments.h
new file mode 100755
index 0000000..91fb587
--- /dev/null
+++ b/X-Plane-SDK/CHeaders/Wrappers/XPCWidgetAttachments.h
@@ -0,0 +1,146 @@
+#ifndef _XPCWidgetAttachments_h_
+#define _XPCWidgetAttachments_h_
+
+#include <string>
+
+#include "XPCWidget.h"
+#include "XPCBroadcaster.h"
+
+class XPCKeyFilterAttachment : public XPCWidgetAttachment {
+public:
+
+ XPCKeyFilterAttachment(
+ const char * inValidKeys,
+ const char * outValidKeys);
+ virtual ~XPCKeyFilterAttachment();
+
+ virtual int HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2);
+
+private:
+
+ std::string mInput;
+ std::string mOutput;
+
+};
+
+
+class XPCKeyMessageAttachment : public XPCWidgetAttachment, public XPCBroadcaster {
+public:
+
+ XPCKeyMessageAttachment(
+ char inKey,
+ int inMessage,
+ void * inParam,
+ bool inConsume,
+ bool inVkey,
+ XPCListener * inListener);
+ virtual ~XPCKeyMessageAttachment();
+
+ virtual int HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2);
+
+private:
+
+ char mKey;
+ bool mVkey;
+ int mMsg;
+ void * mParam;
+ bool mConsume;
+
+};
+
+class XPCPushButtonMessageAttachment : public XPCWidgetAttachment, XPCBroadcaster {
+public:
+
+ XPCPushButtonMessageAttachment(
+ XPWidgetID inWidget,
+ int inMessage,
+ void * inParam,
+ XPCListener * inListener);
+ virtual ~XPCPushButtonMessageAttachment();
+
+ virtual int HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2);
+
+private:
+ XPWidgetID mWidget;
+ int mMsg;
+ void * mParam;
+};
+
+class XPCSliderMessageAttachment : public XPCWidgetAttachment, XPCBroadcaster {
+public:
+
+ XPCSliderMessageAttachment(
+ XPWidgetID inWidget,
+ int inMessage,
+ void * inParam,
+ XPCListener * inListener);
+ virtual ~XPCSliderMessageAttachment();
+
+ virtual int HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2);
+
+private:
+ XPWidgetID mWidget;
+ int mMsg;
+ void * mParam;
+};
+
+
+class XPCCloseButtonMessageAttachment : public XPCWidgetAttachment, XPCBroadcaster {
+public:
+
+ XPCCloseButtonMessageAttachment(
+ XPWidgetID inWidget,
+ int inMessage,
+ void * inParam,
+ XPCListener * inListener);
+ virtual ~XPCCloseButtonMessageAttachment();
+
+ virtual int HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2);
+
+private:
+ XPWidgetID mWidget;
+ int mMsg;
+ void * mParam;
+};
+
+class XPCTabGroupAttachment : public XPCWidgetAttachment {
+public:
+
+ XPCTabGroupAttachment();
+ virtual ~XPCTabGroupAttachment();
+
+ virtual int HandleWidgetMessage(
+ XPCWidget * inObject,
+ XPWidgetMessage inMessage,
+ XPWidgetID inWidget,
+ intptr_t inParam1,
+ intptr_t inParam2);
+
+};
+
+#endif \ No newline at end of file