mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
Working on a new display widget
This commit is contained in:
parent
38dfba80f0
commit
ebd40b3182
@ -369,12 +369,10 @@ class MyFrame(wx.Frame):
|
||||
size=(self.WIDTH_SCREEN, self.HEIGHT_SCREEN),
|
||||
pos=(0,0))
|
||||
self.screen.SetBackgroundColour(self.SCREEN_COLOUR)
|
||||
self.screen.Bind(wx.EVT_PAINT, self.on_paint)
|
||||
self.console = wx.Panel(self, style=wx.SIMPLE_BORDER,
|
||||
size=(self.WIDTH_CONSOLE, self.HEIGHT_SCREEN),
|
||||
pos=(self.WIDTH_SCREEN,0))
|
||||
self.console.SetBackgroundColour(self.CONSOLE_COLOUR)
|
||||
self.console.Bind(wx.EVT_PAINT, self.on_paint)
|
||||
|
||||
python_png = wx.Image('images/PythonPowered.png',
|
||||
wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
@ -698,12 +696,10 @@ class MyFrame(wx.Frame):
|
||||
size=(self.WIDTH_SCREEN, self.HEIGHT_SCREEN),
|
||||
pos=(0,0))
|
||||
self.screen.SetBackgroundColour(self.SCREEN_COLOUR)
|
||||
self.screen.Bind(wx.EVT_PAINT, self.on_paint)
|
||||
self.console = wx.Panel(self, style=wx.SIMPLE_BORDER,
|
||||
size=(self.WIDTH_CONSOLE, self.HEIGHT_SCREEN),
|
||||
pos=(self.WIDTH_SCREEN,0))
|
||||
self.console.SetBackgroundColour(self.CONSOLE_COLOUR)
|
||||
self.console.Bind(wx.EVT_PAINT, self.on_paint)
|
||||
|
||||
python_png = wx.Image('images/PythonPowered.png',
|
||||
wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
@ -786,6 +782,9 @@ class MyFrame(wx.Frame):
|
||||
|
||||
self.Fit()
|
||||
|
||||
self.screen.Bind(wx.EVT_PAINT, self.on_paint)
|
||||
self.console.Bind(wx.EVT_PAINT, self.on_paint)
|
||||
|
||||
def on_paint(self, event):
|
||||
global count
|
||||
|
||||
|
||||
268
pymlac/pymlac_display.py
Executable file
268
pymlac/pymlac_display.py
Executable file
@ -0,0 +1,268 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
A display widget for the pymlac interpreter.
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import wx
|
||||
|
||||
# if we don't have log.py, don't crash
|
||||
try:
|
||||
import log
|
||||
log = log.Log('test.log', log.Log.DEBUG)
|
||||
except ImportError:
|
||||
def log(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
# the widget version
|
||||
__version__ = '0.0'
|
||||
|
||||
# type of events
|
||||
DisplayStop = 1
|
||||
|
||||
|
||||
######
|
||||
# Base class for the widget canvas - buffered and flicker-free.
|
||||
######
|
||||
|
||||
class _BufferedCanvas(wx.Panel):
|
||||
"""Implements a buffered, flicker-free canvas widget.
|
||||
|
||||
This class is based on:
|
||||
http://wiki.wxpython.org/index.cgi/BufferedCanvas
|
||||
"""
|
||||
|
||||
# The backing buffer
|
||||
buffer = None
|
||||
|
||||
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize, style=wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||
"""Initialise the canvas.
|
||||
|
||||
parent reference to 'parent' widget
|
||||
id the unique widget ID (NB: shadows builtin 'id')
|
||||
pos canvas position
|
||||
size canvas size
|
||||
style wxPython style
|
||||
"""
|
||||
|
||||
wx.Panel.__init__(self, parent, id, pos, size, style)
|
||||
|
||||
# Bind events
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
self.Bind(wx.EVT_SIZE, self.OnSize)
|
||||
|
||||
# Disable background erasing (flicker-licious)
|
||||
def disable_event(*args, **kwargs):
|
||||
pass # the sauce, please
|
||||
self.Bind(wx.EVT_ERASE_BACKGROUND, disable_event)
|
||||
|
||||
# set callback upon onSize event
|
||||
self.onSizeCallback = None
|
||||
|
||||
def Draw(self, dc):
|
||||
"""Stub: called when the canvas needs to be re-drawn."""
|
||||
|
||||
pass
|
||||
|
||||
def Update(self):
|
||||
"""Causes the canvas to be updated."""
|
||||
|
||||
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
|
||||
dc.BeginDrawing()
|
||||
dc.Clear() # because maybe view size > map size
|
||||
self.Draw(dc)
|
||||
dc.EndDrawing()
|
||||
|
||||
def OnPaint(self, event):
|
||||
"""Paint the canvas to the screen."""
|
||||
|
||||
# Blit the front buffer to the screen
|
||||
wx.BufferedPaintDC(self, self.buffer)
|
||||
|
||||
def OnSize(self, event=None):
|
||||
"""Create a new off-screen buffer to hold drawn data."""
|
||||
|
||||
(width, height) = self.GetClientSizeTuple()
|
||||
if width == 0:
|
||||
width = 1
|
||||
if height == 0:
|
||||
height = 1
|
||||
|
||||
minsize = min(width, height)
|
||||
self.SetSize((minsize, minsize))
|
||||
|
||||
self.view_width = minsize
|
||||
self.view_height = minsize
|
||||
|
||||
# new off-screen buffer
|
||||
self.buffer = wx.EmptyBitmap(minsize, minsize)
|
||||
|
||||
# call onSize callback, if registered
|
||||
if self.onSizeCallback:
|
||||
self.onSizeCallback()
|
||||
|
||||
# Now update the screen
|
||||
self.Update()
|
||||
|
||||
###############################################################################
|
||||
# Define the events that are raised by the display widget.
|
||||
###############################################################################
|
||||
|
||||
# display stop
|
||||
_myEVT_DISPLAY_STOP = wx.NewEventType()
|
||||
EVT_DISPLAY_STOP = wx.PyEventBinder(_myEVT_DISPLAY_STOP, 1)
|
||||
|
||||
class _DisplayEvent(wx.PyCommandEvent):
|
||||
"""Event sent from the display widget."""
|
||||
|
||||
def __init__(self, eventType, id):
|
||||
"""Construct a display event.
|
||||
|
||||
eventType type of event
|
||||
id unique event number
|
||||
|
||||
Event will be adorned with attributes by raising code.
|
||||
"""
|
||||
|
||||
wx.PyCommandEvent.__init__(self, eventType, id)
|
||||
|
||||
###############################################################################
|
||||
# The display widget proper
|
||||
###############################################################################
|
||||
|
||||
class PymlacDisplay(_BufferedCanvas):
|
||||
"""A widget to display pymlac draw lists."""
|
||||
|
||||
# line colour
|
||||
DrawColour = '#ffff00'
|
||||
|
||||
# panel background colour
|
||||
BackgroundColour = '#000000'
|
||||
|
||||
# max coorcinates of pymlac display
|
||||
PymlacMaxX = 1024
|
||||
PymlaxMaxY = 1024
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
"""Initialise a display instance.
|
||||
|
||||
parent reference to parent object
|
||||
**kwargs keyword args for Panel
|
||||
"""
|
||||
|
||||
# create and initialise the base panel
|
||||
_BufferedCanvas.__init__(self, parent=parent, **kwargs)
|
||||
self.SetBackgroundColour(PymlacDisplay.BackgroundColour)
|
||||
|
||||
# set some internal state
|
||||
self.default_cursor = wx.CURSOR_DEFAULT
|
||||
self.drawlist = None # list of (x1,y1,x2,y2)
|
||||
|
||||
# set callback when parent resizes
|
||||
# self.onSizeCallback = self.ResizeCallback
|
||||
|
||||
# force a resize, which sets up the rest of the state
|
||||
# eventually calls ResizeCallback()
|
||||
self.OnSize()
|
||||
|
||||
######
|
||||
# GUI stuff
|
||||
######
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
pass
|
||||
|
||||
def OnKeyUp(self, event):
|
||||
pass
|
||||
|
||||
def OnLeftUp(self, event):
|
||||
"""Left mouse button up.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
def OnMiddleUp(self, event):
|
||||
"""Middle mouse button up. Do nothing in this version."""
|
||||
|
||||
pass
|
||||
|
||||
def OnRightUp(self, event):
|
||||
"""Right mouse button up.
|
||||
|
||||
Note that when we iterate through the layer_z_order list we must
|
||||
iterate on a *copy* as the user select process can modify
|
||||
self.layer_z_order.
|
||||
|
||||
THIS CODE HASN'T BEEN LOOKED AT IN A LONG, LONG TIME.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
def Draw(self, dc):
|
||||
"""Do actual widget drawing.
|
||||
Overrides the _BufferedCanvas.draw() method.
|
||||
|
||||
dc device context to draw on
|
||||
|
||||
Draws the current drawlist to the screen.
|
||||
"""
|
||||
|
||||
scaleX = self.view_width*1.0 / self.PymlacMaxX
|
||||
scaleY = self.view_height*1.0 / self.PymlaxMaxY
|
||||
dc.SetUserScale(min(scaleX,scaleY), min(scaleX,scaleY))
|
||||
|
||||
if self.drawlist:
|
||||
dc.SetPen(wx.Pen(self.DrawColour))
|
||||
dc.DrawLineList(self.drawlist)
|
||||
|
||||
######
|
||||
# Change the drawlist
|
||||
######
|
||||
|
||||
def Drawlist(self, dl):
|
||||
self.drawlist = dl
|
||||
self.Update()
|
||||
|
||||
######
|
||||
# Routines for display events
|
||||
######
|
||||
|
||||
def RaiseEventStop(self):
|
||||
"""Raise a display stop event."""
|
||||
|
||||
event = _DisplayEvent(_myEVT_DISPLAY_STOP, self.GetId())
|
||||
self.GetEventHandler().ProcessEvent(event)
|
||||
|
||||
def info(self, msg):
|
||||
"""Display an information message, log and graphically."""
|
||||
|
||||
log_msg = '# ' + msg
|
||||
length = len(log_msg)
|
||||
prefix = '#### Information '
|
||||
banner = prefix + '#'*(80 - len(log_msg) - len(prefix))
|
||||
log(banner)
|
||||
log(log_msg)
|
||||
log(banner)
|
||||
|
||||
wx.MessageBox(msg, 'Warning', wx.OK | wx.ICON_INFORMATION)
|
||||
|
||||
def warn(self, msg):
|
||||
"""Display a warning message, log and graphically."""
|
||||
|
||||
log_msg = '# ' + msg
|
||||
length = len(log_msg)
|
||||
prefix = '#### Warning '
|
||||
banner = prefix + '#'*(80 - len(log_msg) - len(prefix))
|
||||
log(banner)
|
||||
log(log_msg)
|
||||
log(banner)
|
||||
|
||||
wx.MessageBox(msg, 'Warning', wx.OK | wx.ICON_ERROR)
|
||||
|
||||
117
pymlac/test_pymlac_display.py
Executable file
117
pymlac/test_pymlac_display.py
Executable file
@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test the pymlac display widget.
|
||||
|
||||
Usage: test_pymlac_display.py [-h]
|
||||
"""
|
||||
|
||||
|
||||
import wx
|
||||
import pymlac_display as Display
|
||||
|
||||
# if we don't have log.py, don't crash
|
||||
try:
|
||||
import log
|
||||
log = log.Log('test.log', log.Log.DEBUG)
|
||||
except ImportError:
|
||||
def log(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
######
|
||||
# Various demo constants
|
||||
######
|
||||
|
||||
DefaultAppSize = (200, 200)
|
||||
|
||||
################################################################################
|
||||
# The main application frame
|
||||
################################################################################
|
||||
|
||||
class TestFrame(wx.Frame):
|
||||
def __init__(self):
|
||||
wx.Frame.__init__(self, None, size=DefaultAppSize,
|
||||
title=('Test pymlac display - %s'
|
||||
% Display.__version__))
|
||||
self.SetMinSize(DefaultAppSize)
|
||||
self.panel = wx.Panel(self, wx.ID_ANY)
|
||||
self.panel.ClearBackground()
|
||||
|
||||
# build the GUI
|
||||
box = wx.BoxSizer(wx.VERTICAL)
|
||||
self.display = Display.PymlacDisplay(self.panel)
|
||||
box.Add(self.display, proportion=1, border=1, flag=wx.EXPAND)
|
||||
self.panel.SetSizer(box)
|
||||
self.panel.Layout()
|
||||
self.Centre()
|
||||
self.Show(True)
|
||||
|
||||
self.Bind(wx.EVT_SIZE, self.OnSize)
|
||||
|
||||
self.display.Drawlist([(0,0,1024,1024), (1024,0,0,1024)])
|
||||
|
||||
def OnSize(self, event):
|
||||
"""Maintain square window."""
|
||||
|
||||
if deltaw is None:
|
||||
|
||||
# (fwidth, fheight) = self.GetSize()
|
||||
# log('####: fwidth=%d, fheight=%d' % (fwidth, fheight))
|
||||
#
|
||||
# (pwidth, pheight) = self.display.GetClientSizeTuple()
|
||||
# deltaw = fwidth - pwidth
|
||||
# deltah = fheight - pheight
|
||||
# log('####: deltaw=%d, deltah=%d' % (deltaw, deltah))
|
||||
#
|
||||
# psize = min(pwidth, pheight)
|
||||
# fsize = (pwidth+deltaw, pheight+deltah)
|
||||
# self.SetSize(fsize)
|
||||
|
||||
event.Skip()
|
||||
|
||||
################################################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
import getopt
|
||||
import traceback
|
||||
|
||||
# print some usage information
|
||||
def usage(msg=None):
|
||||
if msg:
|
||||
print(msg+'\n')
|
||||
print(__doc__) # module docstring used
|
||||
|
||||
# our own handler for uncaught exceptions
|
||||
def excepthook(type, value, tb):
|
||||
msg = '\n' + '=' * 80
|
||||
msg += '\nUncaught exception:\n'
|
||||
msg += ''.join(traceback.format_exception(type, value, tb))
|
||||
msg += '=' * 80 + '\n'
|
||||
print msg
|
||||
sys.exit(1)
|
||||
|
||||
# plug our handler into the python system
|
||||
sys.excepthook = excepthook
|
||||
|
||||
# decide which tiles to use, default is GMT
|
||||
argv = sys.argv[1:]
|
||||
|
||||
try:
|
||||
(opts, args) = getopt.getopt(argv, 'h', ['help'])
|
||||
except getopt.error:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
for (opt, param) in opts:
|
||||
if opt in ['-h', '--help']:
|
||||
usage()
|
||||
sys.exit(0)
|
||||
|
||||
# start wxPython app
|
||||
app = wx.App()
|
||||
TestFrame().Show()
|
||||
app.MainLoop()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user