X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/299647acac7960652aadb008775429c1f8ea9b8d..83c8bcfde6906e141051345fdb6c6eb3ca4ec0a2:/wxPython/demo/Joystick.py
diff --git a/wxPython/demo/Joystick.py b/wxPython/demo/Joystick.py
index 2c4113adf0..c94e215507 100644
--- a/wxPython/demo/Joystick.py
+++ b/wxPython/demo/Joystick.py
@@ -1,206 +1,1107 @@
+#----------------------------------------------------------------------------
+# Name: Joystick.py
+# Purpose: Demonstrate use of wx.Joystick
+#
+# Author: Jeff Grimmett (grimmtoo@softhome.net), adapted from original
+# .wdr-derived demo
+#
+# Created: 02-Jan-2004
+# RCS-ID: $Id$
+# Copyright:
+# Licence: wxWindows license
+#----------------------------------------------------------------------------
+#
+
+import math
+import wx
+
+haveJoystick = True
+if wx.Platform == "__WXMAC__":
+ haveJoystick = False
#----------------------------------------------------------------------------
-from wxPython.wx import *
-from joystick_wdr import *
+# Once all supported versions of Python support 32-bit integers on all
+# platforms, this can go up to 32.
+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
+ ))
- 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 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
+ xmin = self.stick.GetXMin()
+ xmax = self.stick.GetXMax()
+ if xmin < 0:
+ xmax += abs(xmin)
+ joyx += abs(xmin)
+ xmin = 0
+ xrange = max(xmax - xmin, 1)
+
+ ymin = self.stick.GetYMin()
+ ymax = self.stick.GetYMax()
+ if ymin < 0:
+ ymax += abs(ymin)
+ joyy += abs(ymin)
+ ymin = 0
+ yrange = max(ymax - ymin, 1)
+
+ # 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 * yratio)
+
+ # 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()
+
+
+#----------------------------------------------------------------------------
+
+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
- def UpdateFields(self):
+ # 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)))
+
+ # 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.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 = s.HasPOV()
+ self.fourDir = s.HasPOV4Dir()
+ self.cts = s.HasPOVCTS()
- def OnJoystick(self, evt):
- self.UpdateFields()
+#----------------------------------------------------------------------------
+
+class POVStatus(wx.Panel):
+ #
+ # Displays static info about the POV control
+ #
+ def __init__(self, parent, stick):
+ self.stick = stick
- # WDR: methods for JoystickTestPanel
+ wx.Panel.__init__(self, parent, -1, size=(100, 100))
- def GetYPositionCtrl(self):
- return self.FindWindowById(ID_Y_Position_Ctrl)
+ 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)
- def GetXPositionCtrl(self):
- return self.FindWindowById(ID_X_Position_Ctrl)
+ 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)
- 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)
+ # Effectively makes the checkboxes read-only.
+ self.Bind(wx.EVT_CHECKBOX, self.Calibrate)
- def GetRudderMaxCtrl(self):
- return self.FindWindowById(ID_Rudder_Max_Ctrl)
- def GetRudderMinCtrl(self):
- return self.FindWindowById(ID_Rudder_Min_Ctrl)
+ def Calibrate(self, evt=None):
+ s = self.stick
+ self.avail.SetValue(s.HasPOV())
+ self.fourDir.SetValue(s.HasPOV4Dir())
+ self.cts.SetValue(s.HasPOVCTS())
- def GetMaxAxesCtrl(self):
- return self.FindWindowById(ID_Max_Axes_Ctrl)
- def GetMaxButtonsCtrl(self):
- return self.FindWindowById(ID_Max_Buttons_Ctrl)
+#----------------------------------------------------------------------------
- def GetZMaxCtrl(self):
- return self.FindWindowById(ID_Z_Max_Ctrl)
+class POVPanel(wx.Panel):
+ def __init__(self, parent, stick):
- def GetYMaxCtrl(self):
- return self.FindWindowById(ID_Y_Max_Ctrl)
+ self.stick = stick
- def GetYMinCtrl(self):
- return self.FindWindowById(ID_Y_Min_Ctrl)
+ wx.Panel.__init__(self, parent, -1, size=(100, 100))
- def GetXMinCtrl(self):
- return self.FindWindowById(ID_X_Min_Ctrl)
+ sizer = wx.BoxSizer(wx.HORIZONTAL)
+ gsizer = wx.BoxSizer(wx.VERTICAL)
- def GetNumSticksCtrl(self):
- return self.FindWindowById(ID_Num_Sticks_Ctrl)
+ 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 GetHasPovCtsCtrl(self):
- return self.FindWindowById(ID_Has_POV_CTS_Ctrl)
+ self.SetSizer(sizer)
+ sizer.Fit(self)
- def GetHasVCtrl(self):
- return self.FindWindowById(ID_Has_V_Ctrl)
- def GetHasUCtrl(self):
- return self.FindWindowById(ID_Has_U_Ctrl)
+ def Calibrate(self):
+ self.display.Calibrate()
+ self.status.Calibrate()
- def GetVPositionCtrl(self):
- return self.FindWindowById(ID_V_Position_Ctrl)
- def GetUPositionCtrl(self):
- return self.FindWindowById(ID_U_Position_Ctrl)
+ def Update(self):
+ self.display.Update()
- def GetPovPositionCtrl(self):
- return self.FindWindowById(ID_POV_Position_Ctrl)
- def GetButtonStateCtrl(self):
- return self.FindWindowById(ID_Button_State_Ctrl)
+#----------------------------------------------------------------------------
- def GetUMaxCtrl(self):
- return self.FindWindowById(ID_U_Max_Ctrl)
+class LED(wx.Panel):
+ def __init__(self, parent, number):
- def GetUMinCtrl(self):
- return self.FindWindowById(ID_U_Min_Ctrl)
+ self.state = -1
+ self.size = (20, 20)
+ self.number = number
- def GetPollingMaxCtrl(self):
- return self.FindWindowById(ID_Polling_Max_Ctrl)
+ self.fn = wx.Font(
+ parent.GetFont().GetPointSize() - 1,
+ parent.GetFont().GetFamily(),
+ parent.GetFont().GetStyle(),
+ wx.BOLD
+ )
- def GetPollingMinCtrl(self):
- return self.FindWindowById(ID_Polling_Min_Ctrl)
+ wx.Panel.__init__(self, parent, -1, size=self.size)
- def GetNumAxesCtrl(self):
- return self.FindWindowById(ID_Num_Axes_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 GetNumButtonsCtrl(self):
- return self.FindWindowById(ID_Num_Buttons_Ctrl)
+ self.buffer = wx.EmptyBitmap(*self.size)
+ dc = wx.BufferedDC(None, self.buffer)
+ self.DrawFace(dc)
+ self.DrawLED(dc)
- def GetXMaxCtrl(self):
- return self.FindWindowById(ID_X_Max_Ctrl)
- def GetZMinCtrl(self):
- return self.FindWindowById(ID_Z_Min_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 GetProdNameCtrl(self):
- return self.FindWindowById(ID_Prod_Name_Ctrl)
- def GetMfgIdCtrl(self):
- return self.FindWindowById(ID_Mfg_ID_Ctrl)
+ def DrawFace(self, dc):
+ dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
+ dc.Clear()
- def GetHasPov4dirCtrl(self):
- return self.FindWindowById(ID_Has_POV_4DIR_Ctrl)
- def GetHasPovCtrl(self):
- return self.FindWindowById(ID_Has_POV_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 GetHasZCtrl(self):
- return self.FindWindowById(ID_Has_Z_Ctrl)
- def GetHasRudderCtrl(self):
- return self.FindWindowById(ID_Has_Rudder_Ctrl)
+ def DrawLED(self, dc):
+ # bitmap size
+ bw, bh = self.size
- def GetRudderPosCtrl(self):
- return self.FindWindowById(ID_Rudder_Pos_Ctrl)
+ # center of bitmap
+ center = bw / 2
- def GetPovCtsPosCtrl(self):
- return self.FindWindowById(ID_POV_CTS_Pos_Ctrl)
+ # calc the 0, 0 origin of the bitmap
+ xorigin = center - (bw / 2)
+ yorigin = center - (bh / 2)
- def GetZPositionCtrl(self):
- return self.FindWindowById(ID_Z_Position_Ctrl)
+ # Optimize drawing a bit (for Win)
+ dc.BeginDrawing()
- # WDR: handler implementations for JoysticktestPanel
+ # 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))
+ dc.DrawCircle(center, center, bw/2)
-#----------------------------------------------------------------------
+ txt = str(self.number)
-def runTest(frame, nb, log):
- win = JoystickTestPanel(nb, -1)
- return win
+ # 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)
+
+ # Calc the center of the LED, and from that
+ # derive the origin of our value.
+ tx = center - (fw/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.WHITE)
+ dc.DrawText(txt, tx, ty)
+
+ # Turn off drawing optimization
+ dc.EndDrawing()
+
+
+ def Update(self):
+ dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
+ self.DrawFace(dc)
+ self.DrawLED(dc)
+
+
+#----------------------------------------------------------------------------
+
+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<
+
+wx.Joystick
+This demo illustrates the use of the wx.Joystick class, which is an interface to
+one or more joysticks attached to your system.
+
+
The data that can be retrieved from the joystick comes in four basic flavors. +All of these are illustrated in the demo. In fact, this demo illustrates everything +you can get from the wx.Joystick control. + +
Getting data from the joystick can be event-driven thanks to four event types associated +with wx.JoystickEvent, or the joystick can be polled programatically to get data on +a regular basis. + +
+ # assume buttonState is what the stick returned, and buttonBit + # is the bit you want to examine + + if (buttonState & ( 1 << buttonBit )) : + # button pressed, do something with it ++ +
The problem here is that some OSs return a 32-bit value for up to 32 buttons +(imagine that stick!). Python V2.3 will generate an exception for bit +values over 30. For that reason, this demo is limited to 16 buttons. + +
Note that more than one button can be pressed at a time, so be sure to check all of them! + + +
Different methods are provided to retrieve the POV data for a CTS hat +versus a four-way hat. + +
Fortunately, there is an easy workaround. In the top level frame, create a wx.Timer +that will poll the stick at a set interval. Of course, if you do this, you might as +well forgo catching wxEVT_JOYSTICK_* events at all and rely on the timer to do the +polling. + +
Ideally, the timer should be a one-shot; after it fires, collect and process data as +needed, then re-start the timer, possibly using wx.CallAfter(). + + +