scyther/gui/Attackwindow.py

205 lines
5.7 KiB
Python
Raw Normal View History

2006-08-02 13:59:57 +01:00
#!/usr/bin/python
#---------------------------------------------------------------------------
""" Import externals """
import wx
import time
# Python Imaging library?
usePIL = True
try:
import Image
except ImportError:
usePIL = False
2006-08-02 13:59:57 +01:00
#---------------------------------------------------------------------------
""" Import scyther-gui components """
import Icon
#---------------------------------------------------------------------------
class AttackDisplay(wx.ScrolledWindow):
2006-08-02 23:07:29 +01:00
def __init__(self, daddy, parent, attack):
2006-08-02 13:59:57 +01:00
self.win = daddy
2006-08-02 23:07:29 +01:00
self.attack = attack
2006-08-02 13:59:57 +01:00
wx.ScrolledWindow.__init__(self,parent,id=-1)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Image = wx.StaticBitmap(self, -1, wx.EmptyBitmap(1,1))
self.box = wx.BoxSizer(wx.VERTICAL)
self.box.Add(self.Image,1,wx.ALIGN_CENTER)
self.hbox = wx.BoxSizer(wx.HORIZONTAL)
self.hbox.Add(self.box,1,wx.ALIGN_CENTER)
self.SetSizer(self.hbox)
2006-08-04 23:29:51 +01:00
filename = attack.file
if attack.filetype == "png":
self.original = wx.Image(filename,wx.BITMAP_TYPE_PNG)
elif attack.filetype == "ps":
# depends on PIL lib
self.original = Image.open(filename)
else:
print "Unknown file type %s." % (self.filetype)
2006-08-02 13:59:57 +01:00
# TODO self.Bind(wxSizeEvent
def OnSize(self,event):
self.update()
event.Skip()
def update(self):
self.SetScrollbars(0,0,0,0,0,0)
(sw,sh) = self.GetClientSizeTuple()
(W,H) = (sw,sh)
2006-08-02 13:59:57 +01:00
2006-08-07 13:13:39 +01:00
def makefit(W,H):
2006-08-04 23:08:00 +01:00
if self.win.fit:
2006-08-07 13:13:39 +01:00
# determine scaling factors for fitting
wfactor = float(sw) / W
hfactor = float(sh) / H
# select smallest factor (so it will fit)
if hfactor < wfactor:
factor = hfactor
else:
factor = wfactor
# apply scaling factor
W = W * factor
H = H * factor
return (int(W),int(H))
if self.attack.filetype == "png":
bmp = self.original
if not bmp.Ok():
bmp = wx.EmptyBitmap((1,1))
else:
(W,H) = (bmp.GetWidth(), bmp.GetHeight())
if self.win.fit:
2006-08-07 13:13:39 +01:00
(W,H) = makefit(W,H)
bmp = self.original.Scale(W,H)
self.Image.SetBitmap(wx.BitmapFromImage(bmp))
2006-08-07 12:54:43 +01:00
elif self.attack.filetype == "ps":
pil = self.original.copy()
2006-08-07 13:13:39 +01:00
(W,H) = pil.size
(W,H) = makefit(W,H)
# we really only want antialias when it's smaller
2006-08-07 13:13:39 +01:00
pil.thumbnail((W,H),Image.ANTIALIAS)
image = wx.EmptyImage(pil.size[0],pil.size[1])
image.SetData(pil.convert('RGB').tostring())
self.Image.SetBitmap(image.ConvertToBitmap())
else:
print "Unknown file type %s." % (self.attack.filetype)
2006-08-04 23:08:00 +01:00
2006-08-02 13:59:57 +01:00
#self.box.SetItemMinSize(self.Image.GetContainingSizer())
self.box.Layout()
# wx.StaticBitmap(self, -1, bmp, (0, 0), (bmp.GetWidth(), bmp.GetHeight()))
step = 20
xn = int(W / step) + 1
yn = int(H / step) + 1
2006-08-02 13:59:57 +01:00
self.SetScrollbars(step,step,xn,yn,0,0)
self.Refresh()
#---------------------------------------------------------------------------
2006-08-02 13:59:57 +01:00
class AttackWindow(wx.Frame):
def __init__(self,cl):
global usePIL
2006-08-02 13:59:57 +01:00
super(AttackWindow, self).__init__(None, size=(400,800))
self.claim = cl
# TODO maybe fitting defaults should come from Preferences.
# Now, it is default yes if it looks nice (i.e. we are using
# PIL)
if usePIL:
self.fit = True
else:
self.fit = False
2006-08-02 13:59:57 +01:00
self.CreateInteriorWindowComponents()
Icon.ScytherIcon(self)
self.SetTitle()
def SetTitle(self):
tstr = self.claim.stateName(len(self.claim.attacks))
tstr += " for claim %s" % self.claim.id
2006-08-02 13:59:57 +01:00
super(AttackWindow, self).SetTitle(tstr)
def CreateInteriorWindowComponents(self):
''' Create "interior" window components. In this case it is the
attack picture. '''
# Make zoom buttons
sizer = wx.BoxSizer(wx.VERTICAL)
buttons = wx.BoxSizer(wx.HORIZONTAL)
bt = wx.Button(self,wx.ID_ZOOM_100)
buttons.Add(bt,0)
self.Bind(wx.EVT_BUTTON, self.OnZoom100, bt)
bt = wx.Button(self,wx.ID_ZOOM_FIT)
buttons.Add(bt,0)
self.Bind(wx.EVT_BUTTON, self.OnZoomFit, bt)
sizer.Add(buttons, 0, wx.ALIGN_LEFT)
# Add attacks (possible with tabs)
2006-08-02 13:59:57 +01:00
self.displays=[]
2006-08-03 14:40:39 +01:00
attacks = self.claim.attacks
n = len(attacks)
if n <= 1:
2006-08-02 13:59:57 +01:00
# Just a single window
dp = AttackDisplay(self, self, attacks[0])
self.displays.append(dp)
2006-08-02 13:59:57 +01:00
else:
# Multiple tabs
dp = wx.Notebook(self,-1)
2006-08-03 14:40:39 +01:00
for i in range(0,n):
disp = AttackDisplay(self,dp,attacks[i])
2006-08-03 14:40:39 +01:00
classname = "%s %i" % (self.claim.stateName(),(i+1))
dp.AddPage(disp, classname)
2006-08-02 13:59:57 +01:00
self.displays.append(disp)
sizer.Add(dp, 1, wx.EXPAND,1)
2006-08-02 13:59:57 +01:00
self.SetSizer(sizer)
2006-08-02 13:59:57 +01:00
def update(self):
for t in self.displays:
t.update()
def OnFit(self,event):
if self.fit:
self.fit = False
else:
self.fit = True
self.update()
def OnRealSize(self):
self.fit = False
self.update()
def OnSize(self):
self.Refresh()
def OnZoom100(self,evt):
self.fit = False
self.update()
def OnZoomFit(self,evt):
self.fit = True
self.update()