]> git.saurik.com Git - wxWidgets.git/commitdiff
updated Joystick demo, is now wxDesigner-less
authorRobin Dunn <robin@alldunn.com>
Wed, 7 Jan 2004 02:57:40 +0000 (02:57 +0000)
committerRobin Dunn <robin@alldunn.com>
Wed, 7 Jan 2004 02:57:40 +0000 (02:57 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25078 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

wxPython/demo/Joystick.py
wxPython/demo/joystick.wdr [deleted file]
wxPython/demo/joystick_wdr.py [deleted file]

index 2c4113adf0d5c354925fa6a681adcf6e4bc85a53..03ba8e98c7cbc9b75c768f0f44e7b9cef6aab30f 100644 (file)
+#----------------------------------------------------------------------------
+# Name:        Joystick.py
+# Purpose:     Demonstrate use of wx.Joystick
+#
+# Author:      Jeff Grimmett (grimmtoo@softhome.net), adapted from original
+#              .wdr-derived demo
+#
+# Created:     01/02/04
+# RCS-ID:      $Id$
+# Copyright:
+# Licence:     wxWindows license
+#----------------------------------------------------------------------------
+#
+
+import  math
+import  wx
 
 #----------------------------------------------------------------------------
 
-from wxPython.wx import *
-from joystick_wdr import *
+# For convenience
+spacer = (10, 10)
+MAX_BUTTONS = 16
 
+#----------------------------------------------------------------------------
 
-class JoystickTestPanel(wxPanel):
-    def __init__(self, parent, id,
-        pos = wxDefaultPosition, size = wxDefaultSize,
-        style = wxTAB_TRAVERSAL ):
-        wxPanel.__init__(self, parent, id, pos, size, style)
+class Label(wx.StaticText):
+    # A derived StaticText that always aligns right and renders
+    # in a bold font.
+    def __init__(self, parent, label):
+        wx.StaticText.__init__(self, parent, -1, label, style=wx.ALIGN_RIGHT)
 
-        MakeJoystickTestPanel( self, True )
+        self.SetFont(
+            wx.Font(
+                parent.GetFont().GetPointSize(),
+                parent.GetFont().GetFamily(),
+                parent.GetFont().GetStyle(),
+                wx.BOLD
+                ))
+
+#----------------------------------------------------------------------------
+
+
+class JoyGauge(wx.Panel):
+    def __init__(self, parent, stick):
+
+        self.stick = stick
+        size = (100,100)
+        
+        wx.Panel.__init__(self, parent, -1, size=size)
+
+        self.Bind(wx.EVT_PAINT, self.OnPaint)
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+        self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None)
+
+        self.buffer = wx.EmptyBitmap(*size)
+        dc = wx.BufferedDC(None, self.buffer)
+        self.DrawFace(dc)
+        self.DrawJoystick(dc)
+       
+
+    def OnSize(self, event):
+        # The face Bitmap init is done here, to make sure the buffer is always
+        # the same size as the Window
+        w, h  = self.GetClientSize()
+        self.buffer = wx.EmptyBitmap(w,h)
+        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
+        self.DrawFace(dc)
+        self.DrawJoystick(dc)
+
+
+    def DrawFace(self, dc):
+        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
+        dc.Clear()
+
+
+    def OnPaint(self, evt):
+        # When dc is destroyed it will blit self.buffer to the window,
+        # since no other drawing is needed we'll just return and let it
+        # do it's thing
+        dc = wx.BufferedPaintDC(self, self.buffer)
+
+
+    def DrawJoystick(self, dc):
+        # draw the guage as a maxed square in the center of this window.
+        w, h = self.GetClientSize()
+        edgeSize = min(w, h)
+
+        xorigin = (w - edgeSize) / 2
+        yorigin = (h - edgeSize) / 2
+        center = edgeSize / 2
+
+        # Restrict our drawing activities to the square defined
+        # above.
+        dc.SetClippingRegion((xorigin, yorigin), (edgeSize, edgeSize))
+
+        # Optimize drawing a bit (for Win)
+        dc.BeginDrawing()
+
+        dc.SetBrush(wx.Brush(wx.Colour(251, 252, 237)))
+        dc.DrawRectangle((xorigin, yorigin), (edgeSize, edgeSize))
+
+        dc.SetPen(wx.Pen(wx.BLACK, 1, wx.DOT_DASH))
+
+        dc.DrawLine((xorigin, yorigin + center), (xorigin + edgeSize, yorigin + center))
+        dc.DrawLine((xorigin + center, yorigin), (xorigin + center, yorigin + edgeSize))
+
+        if self.stick:
+            # Get the joystick position as a float
+            joyx =  float(self.stick.GetPosition().x)
+            joyy =  float(self.stick.GetPosition().y)
+
+            # Get the joystick range of motion
+            xrange = self.stick.GetXMax() - self.stick.GetXMin()
+            yrange = self.stick.GetYMax() - self.stick.GetYMin()
+
+            # calc a ratio of our range versus the joystick range
+            xratio = float(edgeSize) / xrange
+            yratio = float(edgeSize) / yrange
+
+            # calc the displayable value based on position times ratio
+            xval = int(joyx * xratio)
+            yval = int(joyy * xratio)
+
+            # and normalize the value from our brush's origin
+            x = xval + xorigin
+            y = yval + yorigin
+
+            # Now to draw it.
+            dc.SetPen(wx.Pen(wx.RED, 2))
+            dc.CrossHair((x, y))
+
+        # Turn off drawing optimization
+        dc.EndDrawing()
+
+
+    def Update(self):
+        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
+        self.DrawFace(dc)
+        self.DrawJoystick(dc)
+
+
+#----------------------------------------------------------------------------
+
+class JoyPanel(wx.Panel):
+    def __init__(self, parent, stick):
+
+        self.stick = stick
+
+        wx.Panel.__init__(self, parent, -1)
+
+        sizer = wx.BoxSizer(wx.VERTICAL)
+
+        fn = wx.Font(
+                parent.GetFont().GetPointSize() + 3,
+                parent.GetFont().GetFamily(),
+                parent.GetFont().GetStyle(),
+                wx.BOLD
+                )
+
+        t = wx.StaticText(self, -1, "X - Y Axes", style = wx.ALIGN_CENTRE)
+        t.SetFont(fn)
+        sizer.Add(t, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_HORIZONTAL, 1)
+
+        self.control = JoyGauge(self, self.stick)
+        sizer.Add(self.control, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_HORIZONTAL, 1)
+
+        self.SetSizer(sizer)
+        sizer.Fit(self)
+
+    def Update(self):
+        self.control.Update()
 
-        try:
-            self.stick = wxJoystick()
-            self.stick.SetCapture(self)
-            EVT_JOYSTICK_EVENTS(self, self.OnJoystick)
-            self.UpdateFields()
-        except NotImplementedError, v:
-            wxMessageBox(str(v), "Exception Message")
 
+#----------------------------------------------------------------------------
+
+class POVGauge(wx.Panel):
+    #
+    # Display the current postion of the POV control
+    #
+    def __init__(self, parent, stick):
+
+        self.stick = stick
+        self.size = (100, 100)
+        self.avail = False
+        self.fourDir = False
+        self.cts = False
+
+        wx.Panel.__init__(self, parent, -1, size=self.size)
+
+        self.Bind(wx.EVT_PAINT, self.OnPaint)
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+        self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None)
+
+        self.buffer = wx.EmptyBitmap(*self.size)
+        dc = wx.BufferedDC(None, self.buffer)
+        self.DrawFace(dc)
+        self.DrawPOV(dc)
+
+
+    def OnSize(self, event):
+        # calculate the size of our display and make a buffer for it.
+        w, h  = self.GetClientSize()
+        s = min(w, h)
+        self.size = (s, s)
+        self.buffer = wx.EmptyBitmap(w,h)
+        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
+        self.DrawFace(dc)
+        self.DrawPOV(dc)
+
+    
+    def DrawFace(self, dc):
+        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
+        dc.Clear()
+
+
+    def OnPaint(self, evt):
+        # When dc is destroyed it will blit self.buffer to the window,
+        # since no other drawing is needed we'll just return and let it
+        # do it's thing
+        dc = wx.BufferedPaintDC(self, self.buffer)
+
+
+    def DrawPOV(self, dc):
+        # draw the guage as a maxed circle in the center of this window.
+        w, h = self.GetClientSize()
+        diameter = min(w, h)
+
+        xorigin = (w - diameter) / 2
+        yorigin = (h - diameter) / 2
+        xcenter = xorigin + diameter / 2
+        ycenter = yorigin + diameter / 2
+
+        # Optimize drawing a bit (for Win)
+        dc.BeginDrawing()
+
+        # our 'raster'.
+        dc.SetBrush(wx.Brush(wx.WHITE))
+        dc.DrawCircle((xcenter, ycenter), diameter/2)
+        dc.SetBrush(wx.Brush(wx.BLACK))
+        dc.DrawCircle((xcenter, ycenter), 10)
+
+        # fancy decorations
+        dc.SetPen(wx.Pen(wx.BLACK, 1, wx.DOT_DASH))
+        dc.DrawLine((xorigin, ycenter), (xorigin + diameter, ycenter))
+        dc.DrawLine((xcenter, yorigin), (xcenter, yorigin + diameter))
+
+        if self.stick:
+            if self.avail:
+
+                pos = -1
+
+                # use the appropriate function to get the POV position
+                if self.fourDir:
+                    pos = self.stick.GetPOVPosition()
+
+                if self.cts:
+                    pos = self.stick.GetPOVCTSPosition()
+
+                # trap invalid values
+                if 0 <= pos <= 36000:
+                    vector = 30
+                else:
+                    vector = 0
+
+                # rotate CCW by 90 so that 0 is up.
+                pos = (pos / 100) - 90
+
+                # Normalize
+                if pos < 0:
+                    pos = pos + 360
+
+                # Stolen from wx.lib.analogclock :-)
+                radiansPerDegree = math.pi / 180
+                pointX = int(round(vector * math.cos(pos * radiansPerDegree)))
+                pointY = int(round(vector * math.sin(pos * radiansPerDegree)))
 
-    def UpdateFields(self):
+                # normalise value to match our actual center.
+                nx = pointX + xcenter
+                ny = pointY + ycenter
+
+                # Draw the line
+                dc.SetPen(wx.Pen(wx.BLUE, 2))
+                dc.DrawLine((xcenter, ycenter), (nx, ny))
+
+                # And a little thing to show the endpoint
+                dc.SetBrush(wx.Brush(wx.BLUE))
+                dc.DrawCircle((nx, ny), 8)
+
+        # Turn off drawing optimization
+        dc.EndDrawing()
+
+
+    def Update(self):
+        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
+        self.DrawFace(dc)
+        self.DrawPOV(dc)
+
+
+    def Calibrate(self):
+        s = self.stick
+        self.avail = s.HasPOV()
+        self.fourDir = s.HasPOV4Dir()
+        self.cts = s.HasPOVCTS()
+
+
+#----------------------------------------------------------------------------
+
+class POVStatus(wx.Panel):
+    #
+    # Displays static info about the POV control
+    #
+    def __init__(self, parent, stick):
+
+        self.stick = stick
+
+        wx.Panel.__init__(self, parent, -1, size=(100, 100))
+
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add((20,20))
+        
+        self.avail = wx.CheckBox(self, -1, "Available")
+        sizer.Add(self.avail, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 2)
+
+        self.fourDir = wx.CheckBox(self, -1, "4-Way Only")
+        sizer.Add(self.fourDir, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 2)
+
+        self.cts = wx.CheckBox(self, -1, "Continuous")
+        sizer.Add(self.cts, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 2)
+
+        self.SetSizer(sizer)
+        sizer.Fit(self)
+
+        # Effectively makes the checkboxes read-only.
+        self.Bind(wx.EVT_CHECKBOX, self.Calibrate)
+
+
+    def Calibrate(self, evt=None):
         s = self.stick
-        self.GetXPositionCtrl().SetValue(str(s.GetPosition().x))
-        self.GetYPositionCtrl().SetValue(str(s.GetPosition().y))
-        self.GetZPositionCtrl().SetValue(str(s.GetZPosition()))
-        self.GetPovCtsPosCtrl().SetValue(str(s.GetPOVPosition()))
-        self.GetRudderPosCtrl().SetValue(str(s.GetRudderPosition()))
-        self.GetHasRudderCtrl().SetValue(str(s.HasRudder()))
-        self.GetHasZCtrl().SetValue(str(s.HasZ()))
-        self.GetHasPovCtrl().SetValue(str(s.HasPOV()))
-        self.GetHasPov4dirCtrl().SetValue(str(s.HasPOV4Dir()))
-        self.GetMfgIdCtrl().SetValue(str(s.GetManufacturerId()))
-        self.GetProdNameCtrl().SetValue(str(s.GetProductName()))
-        self.GetZMinCtrl().SetValue(str(s.GetZMin()))
-        self.GetXMaxCtrl().SetValue(str(s.GetXMax()))
-        self.GetNumButtonsCtrl().SetValue(str(s.GetNumberButtons()))
-        self.GetNumAxesCtrl().SetValue(str(s.GetNumberAxes()))
-        self.GetPollingMinCtrl().SetValue(str(s.GetPollingMin()))
-        self.GetPollingMaxCtrl().SetValue(str(s.GetPollingMax()))
-        self.GetUMinCtrl().SetValue(str(s.GetUMin()))
-        self.GetUMaxCtrl().SetValue(str(s.GetUMax()))
-        self.GetButtonStateCtrl().SetValue(str(s.GetButtonState()))
-        self.GetPovPositionCtrl().SetValue(str(s.GetPOVPosition()))
-        self.GetUPositionCtrl().SetValue(str(s.GetUPosition()))
-        self.GetVPositionCtrl().SetValue(str(s.GetVPosition()))
-        self.GetHasUCtrl().SetValue(str(s.HasU()))
-        self.GetHasVCtrl().SetValue(str(s.HasV()))
-        self.GetHasPovCtsCtrl().SetValue(str(s.HasPOVCTS()))
-        self.GetNumSticksCtrl().SetValue(str(s.GetNumberJoysticks()))
-        self.GetXMinCtrl().SetValue(str(s.GetXMin()))
-        self.GetYMinCtrl().SetValue(str(s.GetYMin()))
-        self.GetYMaxCtrl().SetValue(str(s.GetYMax()))
-        self.GetZMaxCtrl().SetValue(str(s.GetZMax()))
-        self.GetMaxButtonsCtrl().SetValue(str(s.GetMaxButtons()))
-        self.GetMaxAxesCtrl().SetValue(str(s.GetMaxAxes()))
-        self.GetRudderMinCtrl().SetValue(str(s.GetRudderMin()))
-        self.GetRudderMaxCtrl().SetValue(str(s.GetRudderMax()))
-        self.GetVMinCtrl().SetValue(str(s.GetVMin()))
-        self.GetVMaxCtrl().SetValue(str(s.GetVMax()))
+        self.avail.SetValue(s.HasPOV())
+        self.fourDir.SetValue(s.HasPOV4Dir())
+        self.cts.SetValue(s.HasPOVCTS())
 
 
-    def OnJoystick(self, evt):
-        self.UpdateFields()
+#----------------------------------------------------------------------------
 
+class POVPanel(wx.Panel):
+    def __init__(self, parent, stick):
 
-    # WDR: methods for JoystickTestPanel
+        self.stick = stick
 
-    def GetYPositionCtrl(self):
-        return self.FindWindowById(ID_Y_Position_Ctrl)
+        wx.Panel.__init__(self, parent, -1, size=(100, 100))
 
-    def GetXPositionCtrl(self):
-        return self.FindWindowById(ID_X_Position_Ctrl)
+        sizer = wx.BoxSizer(wx.HORIZONTAL)
+        gsizer = wx.BoxSizer(wx.VERTICAL)
 
+        sizer.Add((25,25))
+        
+        fn = wx.Font(
+                parent.GetFont().GetPointSize() + 3,
+                parent.GetFont().GetFamily(),
+                parent.GetFont().GetStyle(),
+                wx.BOLD
+                )
+        t = wx.StaticText(self, -1, "POV Control", style = wx.ALIGN_CENTER)
+        t.SetFont(fn)
+        gsizer.Add(t, 0, wx.ALL | wx.EXPAND, 1)
+        
+        self.display = POVGauge(self, stick)
+        gsizer.Add(self.display, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1)
+        sizer.Add(gsizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1)
+        
+        self.status = POVStatus(self, stick)
+        sizer.Add(self.status, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1)
 
-    def GetVMaxCtrl(self):
-        return self.FindWindowById(ID_V_Max_Ctrl)
+        self.SetSizer(sizer)
+        sizer.Fit(self)
 
-    def GetVMinCtrl(self):
-        return self.FindWindowById(ID_V_Min_Ctrl)
 
-    def GetRudderMaxCtrl(self):
-        return self.FindWindowById(ID_Rudder_Max_Ctrl)
+    def Calibrate(self):
+        self.display.Calibrate()
+        self.status.Calibrate()
 
-    def GetRudderMinCtrl(self):
-        return self.FindWindowById(ID_Rudder_Min_Ctrl)
 
-    def GetMaxAxesCtrl(self):
-        return self.FindWindowById(ID_Max_Axes_Ctrl)
+    def Update(self):
+        self.display.Update()
 
-    def GetMaxButtonsCtrl(self):
-        return self.FindWindowById(ID_Max_Buttons_Ctrl)
 
-    def GetZMaxCtrl(self):
-        return self.FindWindowById(ID_Z_Max_Ctrl)
+#----------------------------------------------------------------------------
 
-    def GetYMaxCtrl(self):
-        return self.FindWindowById(ID_Y_Max_Ctrl)
+class LED(wx.Panel):
+    def __init__(self, parent, number):
 
-    def GetYMinCtrl(self):
-        return self.FindWindowById(ID_Y_Min_Ctrl)
+        self.state = -1
+        self.size = (20, 20)
+        self.number = number
 
-    def GetXMinCtrl(self):
-        return self.FindWindowById(ID_X_Min_Ctrl)
+        self.fn = wx.Font(
+                parent.GetFont().GetPointSize() - 1,
+                parent.GetFont().GetFamily(),
+                parent.GetFont().GetStyle(),
+                wx.BOLD
+                )
 
-    def GetNumSticksCtrl(self):
-        return self.FindWindowById(ID_Num_Sticks_Ctrl)
+        wx.Panel.__init__(self, parent, -1, size=self.size)
 
-    def GetHasPovCtsCtrl(self):
-        return self.FindWindowById(ID_Has_POV_CTS_Ctrl)
+        self.Bind(wx.EVT_PAINT, self.OnPaint)
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+        self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None)
 
-    def GetHasVCtrl(self):
-        return self.FindWindowById(ID_Has_V_Ctrl)
+        self.buffer = wx.EmptyBitmap(*self.size)
+        dc = wx.BufferedDC(None, self.buffer)
+        self.DrawFace(dc)
+        self.DrawLED(dc)
 
-    def GetHasUCtrl(self):
-        return self.FindWindowById(ID_Has_U_Ctrl)
 
-    def GetVPositionCtrl(self):
-        return self.FindWindowById(ID_V_Position_Ctrl)
+    def OnSize(self, event):
+        # calculate the size of our display.
+        w, h  = self.GetClientSize()
+        s = min(w, h)
+        self.size = (s, s)
+        self.buffer = wx.EmptyBitmap(*self.size)
+        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
+        self.DrawFace(dc)
+        self.DrawLED(dc)
 
-    def GetUPositionCtrl(self):
-        return self.FindWindowById(ID_U_Position_Ctrl)
 
-    def GetPovPositionCtrl(self):
-        return self.FindWindowById(ID_POV_Position_Ctrl)
+    def DrawFace(self, dc):
+        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
+        dc.Clear()
 
-    def GetButtonStateCtrl(self):
-        return self.FindWindowById(ID_Button_State_Ctrl)
 
-    def GetUMaxCtrl(self):
-        return self.FindWindowById(ID_U_Max_Ctrl)
+    def OnPaint(self, evt):
+        # When dc is destroyed it will blit self.buffer to the window,
+        # since no other drawing is needed we'll just return and let it
+        # do it's thing
+        dc = wx.BufferedPaintDC(self, self.buffer)
 
-    def GetUMinCtrl(self):
-        return self.FindWindowById(ID_U_Min_Ctrl)
 
-    def GetPollingMaxCtrl(self):
-        return self.FindWindowById(ID_Polling_Max_Ctrl)
+    def DrawLED(self, dc):
+        # bitmap size
+        bw, bh = self.size
 
-    def GetPollingMinCtrl(self):
-        return self.FindWindowById(ID_Polling_Min_Ctrl)
+        # center of bitmap
+        center = bw / 2
 
-    def GetNumAxesCtrl(self):
-        return self.FindWindowById(ID_Num_Axes_Ctrl)
+        # calc the 0, 0 origin of the bitmap
+        xorigin = center - (bw / 2)
+        yorigin = center - (bh / 2)
 
-    def GetNumButtonsCtrl(self):
-        return self.FindWindowById(ID_Num_Buttons_Ctrl)
+        # Optimize drawing a bit (for Win)
+        dc.BeginDrawing()
 
-    def GetXMaxCtrl(self):
-        return self.FindWindowById(ID_X_Max_Ctrl)
+        # our 'raster'.
+        if self.state == 0:
+            dc.SetBrush(wx.Brush(wx.RED))
+        elif self.state == 1:
+            dc.SetBrush(wx.Brush(wx.GREEN))
+        else:
+            dc.SetBrush(wx.Brush(wx.BLACK))
 
-    def GetZMinCtrl(self):
-        return self.FindWindowById(ID_Z_Min_Ctrl)
+        dc.DrawCircle((center, center), bw/2)
 
-    def GetProdNameCtrl(self):
-        return self.FindWindowById(ID_Prod_Name_Ctrl)
+        txt = str(self.number)
 
-    def GetMfgIdCtrl(self):
-        return self.FindWindowById(ID_Mfg_ID_Ctrl)
+        # Set the font for the DC ...
+        dc.SetFont(self.fn)
+        # ... and calculate how much space our value
+        # will take up.
+        fw, fh = dc.GetTextExtent(txt)
 
-    def GetHasPov4dirCtrl(self):
-        return self.FindWindowById(ID_Has_POV_4DIR_Ctrl)
+        # Calc the center of the LED, and from that
+        # derive the origin of our value.
+        tx = center - (fw/2)
+        ty = center - (fh/2)
 
-    def GetHasPovCtrl(self):
-        return self.FindWindowById(ID_Has_POV_Ctrl)
+        # I draw the value twice so as to give it a pseudo-shadow.
+        # This is (mostly) because I'm too lazy to figure out how
+        # to blit my text onto the gauge using one of the logical
+        # functions. The pseudo-shadow gives the text contrast
+        # regardless of whether the bar is under it or not.
+        dc.SetTextForeground(wx.WHITE)
+        dc.DrawText(txt, (tx, ty))
 
-    def GetHasZCtrl(self):
-        return self.FindWindowById(ID_Has_Z_Ctrl)
+        # Turn off drawing optimization
+        dc.EndDrawing()
 
-    def GetHasRudderCtrl(self):
-        return self.FindWindowById(ID_Has_Rudder_Ctrl)
 
-    def GetRudderPosCtrl(self):
-        return self.FindWindowById(ID_Rudder_Pos_Ctrl)
+    def Update(self):
+        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
+        self.DrawFace(dc)
+        self.DrawLED(dc)
 
-    def GetPovCtsPosCtrl(self):
-        return self.FindWindowById(ID_POV_CTS_Pos_Ctrl)
 
-    def GetZPositionCtrl(self):
-        return self.FindWindowById(ID_Z_Position_Ctrl)
+#----------------------------------------------------------------------------
 
-    # WDR: handler implementations for JoysticktestPanel
+class JoyButtons(wx.Panel):
+    def __init__(self, parent, stick):
 
+        self.stick = stick
+        self.leds = {}
 
-#----------------------------------------------------------------------
+        wx.Panel.__init__(self, parent, -1)
+
+        tsizer = wx.BoxSizer(wx.VERTICAL)
+
+        fn = wx.Font(
+                parent.GetFont().GetPointSize() + 3,
+                parent.GetFont().GetFamily(),
+                parent.GetFont().GetStyle(),
+                wx.BOLD
+                )
+
+        t = wx.StaticText(self, -1, "Buttons", style = wx.ALIGN_LEFT)
+        t.SetFont(fn)
+        tsizer.Add(t, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 1)
+
+        sizer = wx.FlexGridSizer(4, 16, 2, 2)
+
+        fn.SetPointSize(parent.GetFont().GetPointSize() + 1)
+
+        for i in range(0, MAX_BUTTONS):
+            t = LED(self, i)
+            self.leds[i] = t
+            sizer.Add(t, 1, wx.ALL|wx.ALIGN_CENTER|wx.ALIGN_CENTER_VERTICAL, 1)
+            sizer.AddGrowableCol(i)
+
+        tsizer.Add(sizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 1)
+
+        self.SetSizer(tsizer)
+        tsizer.Fit(self)
+
+    def Calibrate(self):
+        for i in range(0, MAX_BUTTONS):
+            self.leds[i].state = -1
+
+        t = self.stick.GetNumberButtons()
+
+        for i in range(0, t):
+            self.leds[i].state = 0
+
+    def Update(self):
+        t = self.stick.GetButtonState()
+
+        for i in range(0, MAX_BUTTONS):
+            if self.leds[i].state == 1:
+                self.leds[i].state = 0
+
+            if (t & (1<<i)):
+                self.leds[i].state = 1
+
+            self.leds[i].Update()
+
+
+#----------------------------------------------------------------------------
+
+class InfoPanel(wx.Panel):
+    def __init__(self, parent, stick):
+
+        self.stick = stick
+
+        wx.Panel.__init__(self, parent, -1)
+
+        sizer = wx.GridBagSizer(1, 1)
+
+        sizer.Add(Label(self, 'Mfr ID: '), (0, 0), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
+        self.MfgID = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
+        sizer.Add(self.MfgID, (0, 1), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)
+
+        sizer.Add(Label(self, 'Prod Name: '), (0, 2), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
+        self.ProdName = wx.TextCtrl(self, -1, value='', style=wx.TE_READONLY)
+        sizer.Add(self.ProdName, (0, 3), (1, 3), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)
+
+        sizer.Add(Label(self, 'Threshold: '), (0, 6), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
+        self.Threshold = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
+        sizer.Add(self.Threshold, (0, 7), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)
+
+        #----------------------------------------------------------------------------
+        b = wx.Button(self, -1, "Calibrate")
+        sizer.Add(b, (1, 0), (2, 2), wx.ALL | wx.ALIGN_CENTER, 2)
+
+        sizer.Add(Label(self, '# of Sticks: '), (1, 2), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
+        self.NumJoysticks = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
+        sizer.Add(self.NumJoysticks, (1, 3), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)
+
+        sizer.Add(Label(self, '# of Axes: '), (1, 4), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
+        self.NumAxis = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
+        sizer.Add(self.NumAxis, (1, 5), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)
+
+        sizer.Add(Label(self, 'Max # Axes: '), (1, 6), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
+        self.MaxAxis = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
+        sizer.Add(self.MaxAxis, (1, 7), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)
+
+        #----------------------------------------------------------------------------
+
+        sizer.Add(Label(self, 'Polling -- '), (2, 3), (1, 1), wx.ALL | wx.GROW, 2)
+
+        sizer.Add(Label(self, 'Min: '), (2, 4), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
+        self.PollMin = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
+        sizer.Add(self.PollMin, (2, 5), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)
+
+        sizer.Add(Label(self, 'Max: '), (2, 6), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
+        self.PollMax = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
+        sizer.Add(self.PollMax, (2, 7), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)
+
+        #----------------------------------------------------------------------------
+
+        self.SetSizer(sizer)
+        sizer.Fit(self)
+
+
+    def Calibrate(self):
+        if not self.stick:
+            return
+
+        s = self.stick
+
+        self.MfgID.SetValue(str(s.GetManufacturerId()))
+        self.ProdName.SetValue(str(s.GetProductName()))
+        self.Threshold.SetValue(str(s.GetMovementThreshold()))
+        self.NumJoysticks.SetValue(str(s.GetNumberJoysticks()))
+        self.NumAxis.SetValue(str(s.GetNumberAxes()))
+        self.MaxAxis.SetValue(str(s.GetMaxAxes()))
+        self.PollMin.SetValue(str(s.GetPollingMin()))
+        self.PollMax.SetValue(str(s.GetPollingMax()))
+
+
+#----------------------------------------------------------------------------
+
+class AxisBar(wx.Gauge):
+    #
+    # This class allows us to use a wx.Gauge to display the axis value
+    # with a fancy label overlayed onto the guage itself. Two values are
+    # used to do things: first of all, since the gauge is limited to
+    # positive numbers, the scale is fixed at 0 to 1000. We will receive
+    # an adjusted value to use to render the gauge itself. The other value
+    # is a raw value and actually reflects the value from the joystick itself,
+    # which is then drawn over the gauge.
+    #
+    def __init__(self, parent):
+        wx.Gauge.__init__(self, parent, -1, 1000, size=(-1, 20), style = wx.GA_HORIZONTAL | wx.GA_SMOOTH )
+
+        # This is the value we will display.
+        self.rawvalue = 0
+
+        self.SetBackgroundColour('light blue')
+        self.SetForegroundColour('orange')
+
+        # Capture paint events for purpose of updating
+        # the displayed value.
+        self.Bind(wx.EVT_PAINT, self.onPaint)
+
+    def Update(self, value, rawvalue):
+        # Updates the gauge itself, sets the raw value for
+        # the next EVT_PAINT
+        self.SetValue(value)
+        self.rawvalue = rawvalue
+
+    def onPaint(self, evt):
+        # Must always create a PaintDC when capturing
+        # an EVT_PAINT event
+        self.ShowValue(wx.PaintDC(self), evt)
+
+    def ShowValue(self, dc, evt):
+        # This method handles actual painting of and drawing
+        # on the gauge.
+
+        # Clear out the gauge
+        dc.Clear()
+        # and then carry out business as usual
+        wx.Gauge.OnPaint(self, evt)
+
+        # This is the size available to us.
+        w, h = dc.GetSize()
+
+        # This is what we will overlay on the gauge.
+        # It reflects the actual value received from the
+        # wx.Joystick.
+        txt = str(self.rawvalue)
+
+        # Copy the default font, make it bold.
+        fn = wx.Font(
+                self.GetFont().GetPointSize(),
+                self.GetFont().GetFamily(),
+                self.GetFont().GetStyle(),
+                wx.BOLD
+                )
+
+        # Set the font for the DC ...
+        dc.SetFont(fn)
+        # ... and calculate how much space our value
+        # will take up.
+        fw, fh = dc.GetTextExtent(txt)
+
+        # Calc the center of the gauge, and from that
+        # derive the origin of our value.
+        center = w / 2
+        tx = center - (fw/2)
+
+        center = h / 2
+        ty = center - (fh/2)
+
+        # I draw the value twice so as to give it a pseudo-shadow.
+        # This is (mostly) because I'm too lazy to figure out how
+        # to blit my text onto the gauge using one of the logical
+        # functions. The pseudo-shadow gives the text contrast
+        # regardless of whether the bar is under it or not.
+        dc.SetTextForeground(wx.BLACK)
+        dc.DrawText(txt, (tx, ty))
+
+        dc.SetTextForeground('white')
+        dc.DrawText(txt, (tx-1, ty-1))
+
+
+#----------------------------------------------------------------------------
+
+class Axis(wx.Panel):
+    #
+    # This class is a container for the min, max, and current
+    # values of the joystick axis in question. It contains
+    # also special features to render a 'dummy' if the axis
+    # in question is not available.
+    #
+    def __init__(self, parent, token, stick):
+
+        self.stick = stick
+
+        #
+        # token represents the type of axis we're displaying.
+        #
+        self.token = token
+
+        #
+        # Create a call to the 'Has*()' method for the stick.
+        # X and Y are always there, so we tie the Has* method
+        # to a hardwired True value.
+        #
+        if token not in ['X', 'Y']:
+            self.HasFunc = eval('stick.Has%s' % token)
+        else:
+            self.HasFunc = self.alwaysTrue
+
+        # Now init the panel.
+        wx.Panel.__init__(self, parent, -1)
+
+        sizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        if self.HasFunc():
+            #
+            # Tie our calibration functions to the appropriate
+            # stick method. If we don't have the axis in question,
+            # we won't need them.
+            #
+            self.GetMin = eval('stick.Get%sMin' % token)
+            self.GetMax = eval('stick.Get%sMax' % token)
+
+            # Create our displays and set them up.
+            self.Min = wx.StaticText(self, -1, str(self.GetMin()),
+                                     size=(40,-1), style=wx.ALIGN_RIGHT | wx.ST_NO_AUTORESIZE)
+            self.Max = wx.StaticText(self, -1, str(self.GetMax()),
+                                     size=(40,-1), style=wx.ALIGN_LEFT | wx.ST_NO_AUTORESIZE)
+            self.bar = AxisBar(self)
+
+            sizer.Add(self.Min, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 1)
+            sizer.Add(self.bar, 1, wx.ALL | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL, 1)
+            sizer.Add(self.Max, 0, wx.ALL | wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 1)
+
+        else:
+            # We go here if the axis in question is not available.
+            self.control = wx.StaticText(self, -1, '       *** Not Present ***')
+            sizer.Add(self.control, 1, wx.ALL | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL, 1)
+
+        #----------------------------------------------------------------------------
+
+        self.SetSizer(sizer)
+        sizer.Fit(self)
+        wx.CallAfter(self.Update)
+
+
+    def Calibrate(self):
+        if not self.HasFunc():
+            return
+
+        self.Min.SetLabel(str(self.GetMin()))
+        self.Max.SetLabel(str(self.GetMax()))
+
+
+    def Update(self):
+        # Don't bother if the axis doesn't exist.
+        if not self.HasFunc():
+            return
+
+        min = int(self.Min.GetLabel())
+        max = int(self.Max.GetLabel())
+
+        #
+        # Not all values are available from a wx.JoystickEvent, so I've elected
+        # to not use it at all. Therefore, we are getting our values direct from
+        # the stick. These values also seem to be more stable and reliable than
+        # those received from the event itself, so maybe it's a good idea to
+        # use the stick directly for your program.
+        #
+        # Here we either select the appropriate member of stick.GetPosition() or
+        # apply the appropriate Get*Position method call.
+        #
+        if self.token == 'X':
+            val = self.stick.GetPosition().x
+        elif self.token == 'Y':
+            val = self.stick.GetPosition().y
+        else:
+            val = eval('self.stick.Get%sPosition()' % self.token)
+
+        #
+        # While we might be able to rely on a range of 0-FFFFFF on Win, that might
+        # not be true of all drivers on all platforms. Thus, calc the actual full
+        # range first.
+        #
+        range = float(max - min)
+
+        #
+        # The relative value is used by the derived wx.Gauge since it is a
+        # positive-only control.
+        #
+        relative = 0
+        if range:
+            relative = int(val / range * 1000)
+
+        #
+        # Pass both the raw and relative values to the derived Gauge
+        #
+        self.bar.Update(relative, val)
+
+
+    def alwaysTrue(self):
+        # a dummy method used for X and Y axis.
+        return True
+
+
+#----------------------------------------------------------------------------
+
+class AxisPanel(wx.Panel):
+    #
+    # Contained herein is a panel that offers a graphical display
+    # of the levels for all axes supported by wx.Joystick. If
+    # your system doesn't have a particular axis, it will be
+    # 'dummied' for transparent use.
+    #
+    def __init__(self, parent, stick):
+
+        self.stick = stick
+
+        # Defines labels and 'tokens' to identify each
+        # supporte axis.
+        axesList = [
+            ('X Axis ', 'X'),   ('Y Axis ', 'Y'),
+            ('Z Axis ', 'Z'),   ('Rudder ', 'Rudder'),
+            ('U Axis ', 'U'),   ('V Axis ', 'V')
+            ]
+
+        # Contains a list of all axis initialized.
+        self.axes = []
+
+        wx.Panel.__init__(self, parent, -1)
+
+        sizer = wx.FlexGridSizer(3, 4, 1, 1)
+        sizer.AddGrowableCol(1)
+        sizer.AddGrowableCol(3)
+
+        #----------------------------------------------------------------------------
+
+        # Go through the list of labels and tokens and add a label and
+        # axis display to the sizer for each.
+        for label, token in axesList:
+            sizer.Add(Label(self, label), 0, wx.ALL | wx.ALIGN_RIGHT, 2)
+            t = Axis(self, token, self.stick)
+            self.axes.append(t)
+            sizer.Add(t, 1, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 2)
+
+        #----------------------------------------------------------------------------
+
+        self.SetSizer(sizer)
+        sizer.Fit(self)
+        wx.CallAfter(self.Update)
+
+    def Calibrate(self):
+        for i in self.axes:
+            i.Calibrate()
+
+    def Update(self):
+        for i in self.axes:
+            i.Update()
+
+
+#----------------------------------------------------------------------------
+
+class JoystickDemoPanel(wx.Panel):
+
+    def __init__(self, parent, log):
+
+        self.log = log
+
+        wx.Panel.__init__(self, parent, -1)
+
+        # Try to grab the control. If we get it, capture the stick.
+        # Otherwise, throw up an exception message and play stupid.
+        try:
+            self.stick = wx.Joystick()
+            self.stick.SetCapture(self)
+            # Calibrate our controls
+            wx.CallAfter(self.Calibrate)
+            wx.CallAfter(self.OnJoystick)
+        except NotImplementedError, v:
+            wx.MessageBox(str(v), "Exception Message")
+            self.stick = None
+
+        # One Sizer to Rule Them All...
+        sizer = wx.GridBagSizer(2,2)
+
+        self.info = InfoPanel(self, self.stick)
+        sizer.Add(self.info, (0, 0), (1, 3), wx.ALL | wx.GROW, 2)
+
+        self.info.Bind(wx.EVT_BUTTON, self.Calibrate)
+
+        self.joy = JoyPanel(self, self.stick)
+        sizer.Add(self.joy, (1, 0), (1, 1), wx.ALL | wx.GROW, 2)
+                  
+        self.pov = POVPanel(self, self.stick)
+        sizer.Add(self.pov, (1, 1), (1, 2), wx.ALL | wx.GROW, 2)
+        
+        self.axes = AxisPanel(self, self.stick)
+        sizer.Add(self.axes, (2, 0), (1, 3), wx.ALL | wx.GROW, 2)
+
+        self.buttons = JoyButtons(self, self.stick)
+        sizer.Add(self.buttons, (3, 0), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL, 1)
+
+        self.SetSizer(sizer)
+        sizer.Fit(self)
+
+        # Capture Joystick events (if they happen)
+        self.Bind(wx.EVT_JOYSTICK_EVENTS, self.OnJoystick)
+
+        self.stick.SetMovementThreshold(10)
+
+    def Calibrate(self, evt=None):
+        # Do not try this without a stick
+        if not self.stick:
+            return
+
+        self.info.Calibrate()
+        self.axes.Calibrate()
+        self.pov.Calibrate()
+        self.buttons.Calibrate()
+
+    def OnJoystick(self, evt=None):
+        if not self.stick:
+            return
+
+        self.axes.Update()
+        self.joy.Update()
+        self.pov.Update()
+        self.buttons.Update()
+
+
+#----------------------------------------------------------------------------
 
 def runTest(frame, nb, log):
-    win = JoystickTestPanel(nb, -1)
+    win = JoystickDemoPanel(nb, log)
     return win
 
-#----------------------------------------------------------------------
-
+#----------------------------------------------------------------------------
 
 overview = """\
-"""
 
 
+"""
 
+#----------------------------------------------------------------------------
 
 if __name__ == '__main__':
     import sys,os
     import run
     run.main(['', os.path.basename(sys.argv[0])])
-
diff --git a/wxPython/demo/joystick.wdr b/wxPython/demo/joystick.wdr
deleted file mode 100644 (file)
index 41a2a07..0000000
Binary files a/wxPython/demo/joystick.wdr and /dev/null differ
diff --git a/wxPython/demo/joystick_wdr.py b/wxPython/demo/joystick_wdr.py
deleted file mode 100644 (file)
index 7e4492b..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-#-----------------------------------------------------------------------------
-# Python source generated by wxDesigner from file: joystick.wdr
-# Do not modify this file, all changes will be lost!
-#-----------------------------------------------------------------------------
-
-# Include wxWindows' modules
-from wxPython.wx import *
-
-# Window functions
-
-ID_TEXT = 10000
-ID_X_Position_Ctrl = 10001
-ID_Y_Position_Ctrl = 10002
-ID_Z_Position_Ctrl = 10003
-ID_Button_State_Ctrl = 10004
-ID_POV_Position_Ctrl = 10005
-ID_POV_CTS_Pos_Ctrl = 10006
-ID_Rudder_Pos_Ctrl = 10007
-ID_U_Position_Ctrl = 10008
-ID_V_Position_Ctrl = 10009
-ID_Has_Rudder_Ctrl = 10010
-ID_Has_Z_Ctrl = 10011
-ID_Has_U_Ctrl = 10012
-ID_Has_V_Ctrl = 10013
-ID_Has_POV_Ctrl = 10014
-ID_Has_POV_4DIR_Ctrl = 10015
-ID_Has_POV_CTS_Ctrl = 10016
-ID_Num_Sticks_Ctrl = 10017
-ID_Mfg_ID_Ctrl = 10018
-ID_Prod_Name_Ctrl = 10019
-ID_X_Min_Ctrl = 10020
-ID_Y_Min_Ctrl = 10021
-ID_Z_Min_Ctrl = 10022
-ID_X_Max_Ctrl = 10023
-ID_Y_Max_Ctrl = 10024
-ID_Z_Max_Ctrl = 10025
-ID_Num_Buttons_Ctrl = 10026
-ID_Num_Axes_Ctrl = 10027
-ID_Max_Buttons_Ctrl = 10028
-ID_Max_Axes_Ctrl = 10029
-ID_Polling_Min_Ctrl = 10030
-ID_Polling_Max_Ctrl = 10031
-ID_Rudder_Min_Ctrl = 10032
-ID_Rudder_Max_Ctrl = 10033
-ID_U_Min_Ctrl = 10034
-ID_U_Max_Ctrl = 10035
-ID_V_Min_Ctrl = 10036
-ID_V_Max_Ctrl = 10037
-
-def MakeJoystickTestPanel( parent, call_fit = True, set_sizer = True ):
-    item0 = wxBoxSizer( wxVERTICAL )
-
-    item1 = wxFlexGridSizer( 0, 8, 0, 0 )
-
-    item2 = wxStaticText( parent, ID_TEXT, "X Position:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item2, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item3 = wxTextCtrl( parent, ID_X_Position_Ctrl, "", wxDefaultPosition, wxSize(45,-1), wxTE_READONLY )
-    item1.AddWindow( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item4 = wxStaticText( parent, ID_TEXT, "Y Position:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item4, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item5 = wxTextCtrl( parent, ID_Y_Position_Ctrl, "", wxDefaultPosition, wxSize(45,-1), wxTE_READONLY )
-    item1.AddWindow( item5, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item6 = wxStaticText( parent, ID_TEXT, "Z Position:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item6, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item7 = wxTextCtrl( parent, ID_Z_Position_Ctrl, "", wxDefaultPosition, wxSize(45,-1), wxTE_READONLY )
-    item1.AddWindow( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item8 = wxStaticText( parent, ID_TEXT, "Button State:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item8, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item9 = wxTextCtrl( parent, ID_Button_State_Ctrl, "", wxDefaultPosition, wxSize(45,-1), wxTE_READONLY )
-    item1.AddWindow( item9, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item10 = wxStaticText( parent, ID_TEXT, "POV Position:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item10, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item11 = wxTextCtrl( parent, ID_POV_Position_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item11, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item12 = wxStaticText( parent, ID_TEXT, "POV CTS Pos:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item12, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item13 = wxTextCtrl( parent, ID_POV_CTS_Pos_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item13, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item14 = wxStaticText( parent, ID_TEXT, "Rudder Pos:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item14, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item15 = wxTextCtrl( parent, ID_Rudder_Pos_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item15, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item16 = wxStaticText( parent, ID_TEXT, "U Position:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item16, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item17 = wxTextCtrl( parent, ID_U_Position_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item17, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item18 = wxStaticText( parent, ID_TEXT, "V Position:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item18, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item19 = wxTextCtrl( parent, ID_V_Position_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item19, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item1.AddSpacer( 20, 10, 0, wxALIGN_CENTRE, 5 )
-
-    item1.AddSpacer( 20, 10, 0, wxALIGN_CENTRE, 5 )
-
-    item1.AddSpacer( 20, 10, 0, wxALIGN_CENTRE, 5 )
-
-    item1.AddSpacer( 20, 10, 0, wxALIGN_CENTRE, 5 )
-
-    item1.AddSpacer( 20, 10, 0, wxALIGN_CENTRE, 5 )
-
-    item1.AddSpacer( 20, 10, 0, wxALIGN_CENTRE, 5 )
-
-    item20 = wxStaticText( parent, ID_TEXT, "HasRudder:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item20, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item21 = wxTextCtrl( parent, ID_Has_Rudder_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item21, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item22 = wxStaticText( parent, ID_TEXT, "HasZ:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item22, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item23 = wxTextCtrl( parent, ID_Has_Z_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item23, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item24 = wxStaticText( parent, ID_TEXT, "HasU:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item24, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item25 = wxTextCtrl( parent, ID_Has_U_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item25, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item26 = wxStaticText( parent, ID_TEXT, "HasV:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item26, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item27 = wxTextCtrl( parent, ID_Has_V_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item27, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item28 = wxStaticText( parent, ID_TEXT, "HasPOV:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item28, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item29 = wxTextCtrl( parent, ID_Has_POV_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item29, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item30 = wxStaticText( parent, ID_TEXT, "HasPOV4Dir:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item30, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item31 = wxTextCtrl( parent, ID_Has_POV_4DIR_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item31, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item32 = wxStaticText( parent, ID_TEXT, "HasPOVCTS:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item32, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item33 = wxTextCtrl( parent, ID_Has_POV_CTS_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item33, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item34 = wxStaticText( parent, ID_TEXT, "# Joysticks:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item34, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item35 = wxTextCtrl( parent, ID_Num_Sticks_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item35, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item36 = wxStaticText( parent, ID_TEXT, "Mfg ID:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item36, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item37 = wxTextCtrl( parent, ID_Mfg_ID_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item37, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item38 = wxStaticText( parent, ID_TEXT, "Prod Name:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item38, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item39 = wxTextCtrl( parent, ID_Prod_Name_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item39, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item40 = wxStaticText( parent, ID_TEXT, "X Min:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item40, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item41 = wxTextCtrl( parent, ID_X_Min_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item41, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item42 = wxStaticText( parent, ID_TEXT, "Y Min:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item42, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item43 = wxTextCtrl( parent, ID_Y_Min_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item43, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item44 = wxStaticText( parent, ID_TEXT, "Z Min:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item44, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item45 = wxTextCtrl( parent, ID_Z_Min_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item45, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item46 = wxStaticText( parent, ID_TEXT, "X Max:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item46, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item47 = wxTextCtrl( parent, ID_X_Max_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item47, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item48 = wxStaticText( parent, ID_TEXT, "Y Max:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item48, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item49 = wxTextCtrl( parent, ID_Y_Max_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item49, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item50 = wxStaticText( parent, ID_TEXT, "Z Max", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item50, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item51 = wxTextCtrl( parent, ID_Z_Max_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item51, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item52 = wxStaticText( parent, ID_TEXT, "# Buttons:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item52, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item53 = wxTextCtrl( parent, ID_Num_Buttons_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item53, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item54 = wxStaticText( parent, ID_TEXT, "Num Axes:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item54, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item55 = wxTextCtrl( parent, ID_Num_Axes_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item55, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item56 = wxStaticText( parent, ID_TEXT, "Max Buttons:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item56, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item57 = wxTextCtrl( parent, ID_Max_Buttons_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item57, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item58 = wxStaticText( parent, ID_TEXT, "Max Axes:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item58, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item59 = wxTextCtrl( parent, ID_Max_Axes_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item59, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item60 = wxStaticText( parent, ID_TEXT, "Polling Min:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item60, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item61 = wxTextCtrl( parent, ID_Polling_Min_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item61, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item62 = wxStaticText( parent, ID_TEXT, "Polling Max:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item62, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item63 = wxTextCtrl( parent, ID_Polling_Max_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item63, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item64 = wxStaticText( parent, ID_TEXT, "Rudder Min:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item64, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item65 = wxTextCtrl( parent, ID_Rudder_Min_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item65, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item66 = wxStaticText( parent, ID_TEXT, "Rudder Max:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item66, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item67 = wxTextCtrl( parent, ID_Rudder_Max_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item67, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item68 = wxStaticText( parent, ID_TEXT, "U Min:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item68, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item69 = wxTextCtrl( parent, ID_U_Min_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item69, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item70 = wxStaticText( parent, ID_TEXT, "U Max:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item70, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item71 = wxTextCtrl( parent, ID_U_Max_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item71, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item72 = wxStaticText( parent, ID_TEXT, "V Min:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item72, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item73 = wxTextCtrl( parent, ID_V_Min_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item73, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item74 = wxStaticText( parent, ID_TEXT, "V Max:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT )
-    item1.AddWindow( item74, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 )
-
-    item75 = wxTextCtrl( parent, ID_V_Max_Ctrl, "", wxDefaultPosition, wxSize(35,-1), wxTE_READONLY )
-    item1.AddWindow( item75, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 )
-
-    item0.AddSizer( item1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 15 )
-
-    if set_sizer == True:
-        parent.SetAutoLayout( True )
-        parent.SetSizer( item0 )
-        if call_fit == True:
-            item0.Fit( parent )
-            item0.SetSizeHints( parent )
-
-    return item0
-
-# Menu bar functions
-
-# Bitmap functions
-
-
-# End of generated file