""" RUR-PLE: Roberge's Used Robot - a Python Learning Environment
dialogs.py - dialogs, messages and exceptions used to communicate
with user.
Version 0.8.7
Author: Andre Roberge Copyright 2005
andre.roberge@gmail.com
"""
import wx
from rur_py.translation import _
import images
class MyDialogs(wx.Dialog):
'''Custom dialogs that include "interesting" image and text.'''
def __init__(self, parent, ID, title, mesg, btn_txt, img,
pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.DEFAULT_DIALOG_STYLE, modal=True):
x, y = img.GetWidth(), img.GetHeight()
# leave room for text
size = wx.Size(x, y+100)
# Instead of calling wx.Dialog.__init__ we precreate the dialog
# so we can set an extra style that must be set before
# creation, and then we create the GUI dialog using the Create
# method.
pre = wx.PreDialog()
pre.Create(parent, ID, title, pos, size, style)
# This next step is the most important, it turns this Python
# object into the real wrapper of the dialog (instead of pre)
# as far as the wx.Python extension is concerned.
self.this = pre.this
# Add the message from the exception
wx.StaticText(self,-1, mesg, wx.Point(0,0))
# custom image
wx.StaticBitmap(self, -1, img, wx.Point(0, 40))
btnId = wx.NewId()
button = wx.Button(self, btnId, btn_txt)
x, y = size
button.SetPosition(wx.Point(x/2-30, y-60))
wx.EVT_BUTTON(self, btnId, self.OnCloseMe)
wx.EVT_CLOSE(self, self.OnCloseWindow)
self.CenterOnScreen()
if modal:
self.ShowModal()
else:
self.Show()
def OnCloseMe(self, event):
self.Close(True)
def OnCloseWindow(self, event):
self.Destroy()
#--- Error dialogs
class DialogHitWallError(MyDialogs):
""" Custom dialog """
def __init__(self, excpt):
MyDialogs.__init__(self, None, -1, _("Error"), excpt.mesg,
_("Turn off"), images.HIT_WALL_IMAGE)
class DialogPutBeeperError(MyDialogs):
""" Will need to have its own image """
def __init__(self, excpt):
MyDialogs.__init__(self, None, -1, _("Error"), excpt.mesg,
_("Turn off"), images.HIT_WALL_IMAGE)
class DialogPickBeeperError(MyDialogs):
""" Will need to have its own image """
def __init__(self, excpt):
MyDialogs.__init__(self, None, -1, _("Error"), excpt.mesg,
_("Turn off"), images.HIT_WALL_IMAGE)
class UserStopError(MyDialogs):
""" Will need to have its own image """
def __init__(self, excpt):
MyDialogs.__init__(self, None, -1, _("Error"), excpt.mesg,
_("Turn off"), images.HIT_WALL_IMAGE)
class NoTurnOffError(MyDialogs):
""" Will need to have its own image """
def __init__(self, excpt):
MyDialogs.__init__(self, None, -1, _("Error"), excpt.mesg,
_("Turn off"), images.HIT_WALL_IMAGE)
class NormalEndDialog(MyDialogs):
def __init__(self, excpt):
MyDialogs.__init__(self, None, -1, _("Success!"), excpt.mesg,
"Ok", images.MINI_SPLASH, modal=False)
self.timer = wx.Timer(self)
self.timer.Start(2000)
self.Bind(wx.EVT_TIMER, self.OnCloseMe)
#--- Exceptions
class LogicException(Exception):
'''General class to deal with problematic instructions given to robot.'''
def __init__(self,mesg):
self.mesg = mesg
def __str__(self):
return repr(self.mesg)
class HitWallException(LogicException):
pass
class PutBeeperException(LogicException):
pass
class PickBeeperException(LogicException):
pass
class UserStopException(LogicException):
pass
class NoTurnOffException(LogicException):
pass
class NormalEnd(LogicException):
""" This is a normal condition raised when the program ends properly."""
pass
#--- General Message
def rurMessageDialog(text, title):
messageDialog = wx.MessageDialog(None, text, title,
wx.OK | wx.ICON_INFORMATION)
messageDialog.ShowModal()
messageDialog.Destroy()
#--- New attempt using sliders
class RobotBeeperDialog(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, None, -1, title=title)
p = wx.Panel(self, -1, style = wx.FULL_REPAINT_ON_RESIZE )
self.SetBackgroundColour("wheat")
self.parent = parent
self.world = parent.world
self.WorldDisplay = parent.WorldDisplay
self.robot = parent.world.robot_dict
btnId = wx.NewId()
button = wx.Button(self, btnId, "ok")
wx.EVT_BUTTON(self, btnId, self.OnCloseMe)
wx.EVT_CLOSE(self, self.OnCloseWindow)
self.max1 = 20
self.max2 = 980
if self.robot['robot']._beeper_bag > self.max1:
self.beepers1 = self.max1
self.beepers2 = self.robot['robot']._beeper_bag - self.max1
else:
self.beepers1 = self.robot['robot']._beeper_bag
self.beepers2 = 0
self.slider1 = wx.Slider(self,
# id, value, min, max, (x, y), (length, height)
-1, self.beepers1, 0, self.max1, (0, 0), (250, -1),
wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS
)
self.slider1.SetTickFreq(1, 1)
self.slider2 = wx.Slider(self,
# id, value, min, max, (x, y), (length, height)
-1, self.beepers2, 0, self.max2, (0, 0), (250, -1),
wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS
)
self.slider2.SetTickFreq(35, 1)
mesg = _("""Select the desired value, or sum of values as
the number of beepers to put in the robot's beeper bag.""")
label = wx.StaticText(self, -1, mesg, (0, 0))
gbs = wx.GridBagSizer(10, 10)
gbs.Add(label, (0, 2), (1, 4))
gbs.Add(self.slider1, (1, 2), (1, 4))
gbs.Add(self.slider2, (2, 2), (1, 4))
gbs.Add(button, (3, 3))
self.SetSizerAndFit(gbs)
self.Show()
def OnCloseWindow(self, event):
self.Destroy()
def OnCloseMe(self, event):
num = self.slider1.GetValue()
num += self.slider2.GetValue()
self.robot['robot']._beeper_bag = num
# retrieve backup value
x, y, key, beep = self.parent.backup_dict['robot']
# reset to new value
self.parent.backup_dict['robot'] = x, y, key, num
self.parent.BeepersUpdateStatusBar()
self.Show(False)
self.Destroy()
class ResizeWorldDialog(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, None, -1, title=title)
p = wx.Panel(self, -1, style = wx.FULL_REPAINT_ON_RESIZE )
self.SetBackgroundColour("wheat")
self.parent = parent
self.world = parent.world
self.WorldDisplay = parent.WorldDisplay
self.robot = parent.world.robot_dict
mesg = _("""Select the desired world dimensions (streets and avenues).
The existing walls and beepers will be removed.""")
label = wx.StaticText(self, -1, mesg, (0,0))
min_avenues = 5
min_streets = 5
max_avenues = 30
max_streets = 30
self.streets = parent.world.st
self.avenues = parent.world.av
world_image = wx.StaticBitmap(self, -1, images.EDIT_WORLD, (60, 90))
length, height = world_image.GetSize()
self.slider_street = wx.Slider(
# id, value, min, max, (x, y), (length, height)
self, -1, self.streets, min_streets, max_streets,
(0, 0), (-1, height),
wx.SL_VERTICAL | wx.SL_LABELS | wx.SL_AUTOTICKS
)
self.slider_street.SetTickFreq(1, 1)
self.slider_avenue = wx.Slider(
# id, value, min, max, (x, y), (length, height)
self, -1, self.avenues, min_avenues, max_avenues,
(0, 0), (length, -1),
wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS
)
self.slider_avenue.SetTickFreq(1, 1)
#
btnId = wx.NewId()
button = wx.Button(self, btnId, "ok")
wx.EVT_BUTTON(self, btnId, self.OnCloseMe)
wx.EVT_CLOSE(self, self.OnCloseWindow)
gbs = wx.GridBagSizer(10, 10)
gbs.Add(label, (0, 2), (1, 4))
gbs.Add(self.slider_avenue, (1, 2), (1, 4))
gbs.Add(world_image, (2, 2), (1, 4))
gbs.Add(self.slider_street, (2, 1))
gbs.Add(button, (3, 3))
self.SetSizerAndFit(gbs)
self.Show()
def OnCloseWindow(self, event):
self.Destroy()
def OnCloseMe(self, event):
st = self.slider_street.GetValue()
av = self.slider_avenue.GetValue()
self.world.resetDimensions(av, st)
if 'robot' in self.robot:
self.robot['robot']._setPos(1, 1) # brings robot back to the origin
self.robot['robot']._facing = 3 # facing east
self.robot['robot'].robot_image = \
self.robot['robot']._image[self.robot['robot']._facing]
# prepare to recreate the background images
self.world.background_images_created = False
self.world.AdjustWorldSize()
self.world.InitTileSizes()
self.WorldDisplay.InitialiseVariables()
self.world.DoDrawing()
# create a new bitmap image
self.parent.buffer = wx.EmptyBitmap(self.world.maxWidth,
self.world.maxHeight)
self.WorldDisplay.drawImage()
self.Show(False)
self.Destroy()
|