📄 joystick.py
字号:
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)
self.SetSizer(sizer)
sizer.Fit(self)
def Calibrate(self):
self.display.Calibrate()
self.status.Calibrate()
def Update(self):
self.display.Update()
#----------------------------------------------------------------------------
class LED(wx.Panel):
def __init__(self, parent, number):
self.state = -1
self.size = (20, 20)
self.number = number
self.fn = wx.Font(
parent.GetFont().GetPointSize() - 1,
parent.GetFont().GetFamily(),
parent.GetFont().GetStyle(),
wx.BOLD
)
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.DrawLED(dc)
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 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 DrawLED(self, dc):
# bitmap size
bw, bh = self.size
# center of bitmap
center = bw / 2
# calc the 0, 0 origin of the bitmap
xorigin = center - (bw / 2)
yorigin = center - (bh / 2)
# Optimize drawing a bit (for Win)
dc.BeginDrawing()
# 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)
# 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<<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):
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -