#~ DlgPageA4Zoom2 (tmp name) is a dialog window, that displays a real
#~ print preview of one printer page. I call it real because the
#~ preview dialog displays the physical page and the printable area,
#~ which is correctly positionned on the physical page.
#~ It uses the Pythonwin extensions, so it works only on a win32
#~ platform.
#~ Plotting is achieved in the usual way, through the dc (see
#~ fct DoDraw2).
#~ My problem:
#~ I did not succeed to set the focus on the ScrolledWindow. So,
#~ I cann't move the scrollbars with the arrow keys. A similar
# dialog without the close button and the combo box works.
#~ Attempts without succes:
#~ - no sizers
#~ - wx.Frame instead of wx.Dialog
#~ - two panels
#~ - page and area classes outside the Dialog class
#~ Question:
#~ In this print preview, a zoom of 100% represents a wx.window
#~ having a size equal to the printer dc size (in pixel). What
#~ is a zoom of 100% supposed to represent on the screen?
#~ Any idea is wellcome.
#~ Jean-Michel Fauth, Switzerland
# -*- coding: iso-8859-1 -*-
···
#--------------------------------------------------------------------
# Name: PageA4Zoom4.py
# Purpose:
# Author: Jean-Michel Fauth, Switzerland
# Copyright: (c) 2005 Jean-Michel Fauth
# Licence: GPL
#--------------------------------------------------------------------
# os dev: windows 98
# py dev: Python 2.4.1
# wx dev: wxPython 2.6.1
# Revision: 7 June 2005
#--------------------------------------------------------------------
#--------------------------------------------------------------------
import wx
import win32print
import win32ui
#-------------------------------------------------------------------
#Constants for GetDeviceCaps
HORZSIZE = 4 # Horizontal size in millimeters
VERTSIZE = 6 # Vertical size in millimeters
HORZRES = 8 # Horizontal width in pixels == dc.Width() in wx when
printing
VERTRES = 10 # Vertical width in pixels == dc.Height() in wx when
printing
PHYSICALWIDTH = 110 # Physical Width in device units
PHYSICALHEIGHT = 111 # Physical Height in device units
PHYSICALOFFSETX = 112 # Physical Printable Area x margin
PHYSICALOFFSETY = 113 # Physical Printable Area y margin
#-------------------------------------------------------------------
def DoDraw2(dc):
dc.BeginDrawing()
dcwi, dche = dc.GetSize()
p1x, p1y = 0, 0
p2x, p2y = dcwi, dche
mx, my = dcwi / 2, dche / 2
#plot area
dc.SetPen(wx.Pen(wx.NamedColour('RED')))
dc.DrawRectangle(0, 0, dcwi, dche)
#a square proportional to the dc size, centered on the dc
dc.SetPen(wx.Pen(wx.NamedColour('BLUE')))
side = dcwi * 0.2
dc.DrawRectangle(mx - side / 2, my - side / 2, side, side)
dc.EndDrawing()
#-------------------------------------------------------------------
#- zoom and sizeable -----------------------------------------------
#-------------------------------------------------------------------
class DlgPageA4Zoom2(wx.Dialog):
def __init__(self, parent, id, pos, size):
s = 'Preview'
sty = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER
wx.Dialog.__init__(self, parent, id, s, pos, size, sty)
#get printer name and create a dc
PrinterName = win32print.GetDefaultPrinter()
#~ print 'printer_name:', printer_name
hDC = win32ui.CreateDC()
hDC.CreatePrinterDC(PrinterName)
#get relevant infos
self.PhysicalWidth = hDC.GetDeviceCaps(PHYSICALWIDTH)
self.PhysicalHeight = hDC.GetDeviceCaps(PHYSICALHEIGHT)
self.HorzRes = hDC.GetDeviceCaps(HORZRES)
self.VertRes = hDC.GetDeviceCaps(VERTRES)
self.PhysicalOffsetX = hDC.GetDeviceCaps(PHYSICALOFFSETX)
self.PhysicalOffsetY = hDC.GetDeviceCaps(PHYSICALOFFSETY)
del hDC
self.SetTitle('Preview - ' + PrinterName)
#used widgets
but1 = wx.Button(self, wx.NewId(), 'Close', (-1, -1), (-1, -1))
but1.Bind(wx.EVT_BUTTON, self.OnClick1)
combolist = []
for i in xrange(5, 105, 5):
s = ('%i%%') % (i)
combolist.append(s)
sty = wx.CB_READONLY
self.combo = wx.ComboBox(self, wx.NewId(), '50%', (-1, -1),
(-1, -1), combolist, sty)
self.combo.Bind(wx.EVT_COMBOBOX, self.OnComboBox)
self.combo.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
#default value at ShowModal
self.combo.SetValue('20%')
#real zoom factor
self.zoom = float(self.combo.GetValue().rstrip('%')) / 100.0
#the scrolled window, position and size from vsizer
self.swin = wx.ScrolledWindow(self, wx.NewId(), (-1, -1), (-1, -1),
wx.SUNKEN_BORDER)
c = 120
self.swin.SetBackgroundColour(wx.Colour(c, c, c))
#the page
#position of the page in the scrolled window
self.posinswin = 20
tpos = (self.posinswin, self.posinswin)
tsize = (self.PhysicalWidth * self.zoom, self.PhysicalHeight *
self.zoom)
self.page = wx.Window(self.swin, wx.NewId(), tpos, tsize,
wx.NO_BORDER)
c = 240
self.page.SetBackgroundColour(wx.Colour(c, c, c))
#the printable area
tpos = (self.PhysicalOffsetX * self.zoom, self.PhysicalOffsetY *
self.zoom)
tsize = (self.HorzRes * self.zoom, self.VertRes * self.zoom)
self.area = wx.Window(self.page, wx.NewId(), tpos, tsize,
wx.NO_BORDER)
self.area.SetBackgroundColour(wx.NamedColour('white'))
#set the virtual size and reset the scrollbars
tvsize = (self.PhysicalWidth * self.zoom + 2 * self.posinswin,
self.PhysicalHeight * self.zoom + 2 * self.posinswin)
self.swin.Scroll(0, 0)
self.swin.SetVirtualSize(tvsize)
self.swin.SetScrollRate(1, 1)
#~ self.swin.SetDimensions(20, 20, 300, 300)
#the dlg is sizable, create sizers and place the ctrls
b = 5
hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
hsizer1.Add(but1, 0, wx.ALL, b)
hsizer1.Add(self.combo, 0, wx.ALL, b)
b = 0
vsizer1 = wx.BoxSizer(wx.VERTICAL)
vsizer1.Add(hsizer1, 0, wx.ALIGN_LEFT | wx.ALL, b)
vsizer1.Add(self.swin, 1, wx.EXPAND | wx.ALL, b)
self.SetSizer(vsizer1)
self.swin.SetFocus()
self.area.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, event):
dc = wx.PaintDC(self.area)
self.PrepareDC(dc)
DoDraw2(dc)
def OnClick1(self, event):
self.EndModal(wx.ID_CANCEL)
def OnComboBox(self, event):
self.zoom = float(self.combo.GetValue().rstrip('%')) / 100.0
self.swin.Scroll(0, 0)
self.posinswin = 50
tpos = (self.posinswin, self.posinswin)
tsize = (self.PhysicalWidth * self.zoom, self.PhysicalHeight *
self.zoom)
self.page.SetPosition(tpos)
self.page.SetSize(tsize)
tpos = (self.PhysicalOffsetX * self.zoom, self.PhysicalOffsetY *
self.zoom)
tsize = (self.HorzRes * self.zoom, self.VertRes * self.zoom)
self.area.SetPosition(tpos)
self.area.SetSize(tsize)
tvsize = (self.PhysicalWidth * self.zoom + 2 * self.posinswin,
self.PhysicalHeight * self.zoom + 2 * self.posinswin)
self.swin.SetVirtualSize(tvsize)
self.area.Refresh()
self.swin.SetFocus()
#force a selection with the mouse, tmp hack
def OnKeyDown(self, event):
pass
#-------------------------------------------------------------------
# main app ---------------------------------------------------------
#-------------------------------------------------------------------
class MyPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id, wx.DefaultPosition,
wx.DefaultSize)
b1 = wx.Button(self, wx.NewId(), 'my preview', (20, 20), (-1, -1))
b1.Bind(wx.EVT_BUTTON, self.OnClick1)
def OnClick1(self, event):
dlg = DlgPageA4Zoom2(self, wx.NewId(), (0, 0), (800, 600))
dlg.ShowModal()
#-------------------------------------------------------------------
class MyFrame(wx.Frame):
def __init__(self, parent, id):
s = 'PageA4Zoom'
sty = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, parent, id, s, (20, 20), (300, 200), sty)
pa = MyPanel(self, -1)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
def OnCloseWindow(self, event):
self.Destroy()
#-------------------------------------------------------------------
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1)
frame.Show(True)
self.SetTopWindow(frame)
return True
#-------------------------------------------------------------------
def main():
app = MyApp(0)
app.MainLoop()
#-------------------------------------------------------------------
if __name__ == '__main__':
main()
#eof-------------------------------------------------------------------