mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-27 21:52:25 -06:00
563 lines
19 KiB
Python
563 lines
19 KiB
Python
# --------------------------------------------------------------------------- #
|
|
# ADVANCEDSPLASH Control wxPython IMPLEMENTATION
|
|
# Python Code By:
|
|
#
|
|
# Andrea Gavana, @ 10 Oct 2005
|
|
# Latest Revision: 19 Dec 2012, 21.00 GMT
|
|
#
|
|
#
|
|
# TODO List/Caveats
|
|
#
|
|
# 1. Actually, Setting The Shape Of AdvancedSplash Is Done Using "SetShape"
|
|
# Function On A Frame. This Works, AFAIK, On This Following Platforms:
|
|
#
|
|
# - MSW
|
|
# - UNIX/Linux
|
|
# - MacOS Carbon
|
|
#
|
|
# Obviously I May Be Wrong Here. Could Someone Verify That Lines 139-145
|
|
# Work Correctly On Other Platforms Than Mine (MSW XP/2000)?
|
|
# Moreover, Is There A Way To Avoid The Use Of The "SetShape" Method?
|
|
# I Don't Know.
|
|
#
|
|
#
|
|
# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
|
|
# Write To Me At:
|
|
#
|
|
# andrea.gavana@gmail.com
|
|
# andrea.gavana@maerskoil.com
|
|
#
|
|
# Or, Obviously, To The wxPython Mailing List!!!
|
|
#
|
|
# Tags: phoenix-port, unittest, documented, py3-port
|
|
#
|
|
# End Of Comments
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
"""
|
|
:class:`AdvancedSplash` tries to reproduce the behavior of :class:`~adv.SplashScreen`, with
|
|
some enhancements.
|
|
|
|
|
|
Description
|
|
===========
|
|
|
|
:class:`AdvancedSplash` tries to reproduce the behavior of :class:`~adv.SplashScreen`, but with
|
|
some enhancements (in my opinion).
|
|
|
|
:class:`AdvancedSplash` starts its construction from a simple frame. Then, depending on
|
|
the options passed to it, it sets the frame shape accordingly to the image passed
|
|
as input. :class:`AdvancedSplash` behaves somewhat like :class:`~adv.SplashScreen`, and almost
|
|
all the methods available in :class:`~adv.SplashScreen` are available also in
|
|
this module.
|
|
|
|
|
|
Usage
|
|
=====
|
|
|
|
Sample usage::
|
|
|
|
import wx
|
|
import wx.lib.agw.advancedsplash as AS
|
|
|
|
app = wx.App(0)
|
|
|
|
frame = wx.Frame(None, -1, "AdvancedSplash Test")
|
|
|
|
imagePath = "my_splash_image.png"
|
|
bitmap = wx.Bitmap(imagePath, wx.BITMAP_TYPE_PNG)
|
|
shadow = wx.WHITE
|
|
|
|
splash = AS.AdvancedSplash(frame, bitmap=bitmap, timeout=5000,
|
|
agwStyle=AS.AS_TIMEOUT |
|
|
AS.AS_CENTER_ON_PARENT |
|
|
AS.AS_SHADOW_BITMAP,
|
|
shadowcolour=shadow)
|
|
|
|
app.MainLoop()
|
|
|
|
|
|
None of the options are strictly required (a part of the `bitmap` parameter).
|
|
If you use the defaults you get a very simple :class:`AdvancedSplash`.
|
|
|
|
|
|
Methods and Settings
|
|
====================
|
|
|
|
:class:`AdvancedSplash` is customizable, and in particular you can set:
|
|
|
|
- Whether you want to mask a colour or not in your input bitmap;
|
|
- Where to center the splash screen (on screen, on parent or nowhere);
|
|
- Whether it is a "timeout" splashscreen or not;
|
|
- The time after which :class:`AdvancedSplash` is destroyed (if it is a timeout splashscreen);
|
|
- The (optional) text you wish to display;
|
|
- The font, colour and position of the displayed text (optional).
|
|
|
|
|
|
Window Styles
|
|
=============
|
|
|
|
This class supports the following window styles:
|
|
|
|
======================= =========== ==================================================
|
|
Window Styles Hex Value Description
|
|
======================= =========== ==================================================
|
|
``AS_TIMEOUT`` 0x1 :class:`AdvancedSplash` will be destroyed after `timeout` milliseconds.
|
|
``AS_NOTIMEOUT`` 0x2 :class:`AdvancedSplash` can be destroyed by clicking on it, pressing a key or by explicitly call the `Close()` method.
|
|
``AS_CENTER_ON_SCREEN`` 0x4 :class:`AdvancedSplash` will be centered on screen.
|
|
``AS_CENTER_ON_PARENT`` 0x8 :class:`AdvancedSplash` will be centered on parent.
|
|
``AS_NO_CENTER`` 0x10 :class:`AdvancedSplash` will not be centered.
|
|
``AS_SHADOW_BITMAP`` 0x20 If the bitmap you pass as input has no transparency, you can choose one colour that will be masked in your bitmap. the final shape of :class:`AdvancedSplash` will be defined only by non-transparent (non-masked) pixels.
|
|
======================= =========== ==================================================
|
|
|
|
|
|
Events Processing
|
|
=================
|
|
|
|
`No custom events are available for this class.`
|
|
|
|
|
|
License And Version
|
|
===================
|
|
|
|
:class:`AdvancedSplash` control is distributed under the wxPython license.
|
|
|
|
Latest revision: Andrea Gavana @ 19 Dec 2012, 21.00 GMT
|
|
|
|
Version 0.5
|
|
|
|
"""
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
# Beginning Of ADVANCEDSPLASH wxPython Code
|
|
#----------------------------------------------------------------------
|
|
|
|
import wx
|
|
|
|
# These Are Used To Declare If The AdvancedSplash Should Be Destroyed After The
|
|
# Timeout Or Not
|
|
|
|
AS_TIMEOUT = 1
|
|
""" :class:`AdvancedSplash` will be destroyed after `timeout` milliseconds. """
|
|
AS_NOTIMEOUT = 2
|
|
""" :class:`AdvancedSplash` can be destroyed by clicking on it, pressing a key or by explicitly call the `Close()` method. """
|
|
|
|
# These Flags Are Used To Position AdvancedSplash Correctly On Screen
|
|
AS_CENTER_ON_SCREEN = 4
|
|
""" :class:`AdvancedSplash` will be centered on screen. """
|
|
AS_CENTER_ON_PARENT = 8
|
|
""" :class:`AdvancedSplash` will be centered on parent. """
|
|
AS_NO_CENTER = 16
|
|
""" :class:`AdvancedSplash` will not be centered. """
|
|
|
|
# This Option Allow To Mask A Colour In The Input Bitmap
|
|
AS_SHADOW_BITMAP = 32
|
|
""" If the bitmap you pass as input has no transparency, you can choose one colour that will be masked in your bitmap. the final shape of :class:`AdvancedSplash` will be defined only by non-transparent (non-masked) pixels. """
|
|
|
|
#----------------------------------------------------------------------
|
|
# ADVANCEDSPLASH Class
|
|
# This Is The Main Class Implementation. See __init__() Method For
|
|
# Details.
|
|
#----------------------------------------------------------------------
|
|
|
|
class AdvancedSplash(wx.Frame):
|
|
"""
|
|
:class:`AdvancedSplash` tries to reproduce the behavior of :class:`~adv.SplashScreen`, with
|
|
some enhancements.
|
|
|
|
This is the main class implementation.
|
|
"""
|
|
def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
|
|
style=wx.FRAME_NO_TASKBAR | wx.FRAME_SHAPED | wx.STAY_ON_TOP,
|
|
bitmap=None, timeout=5000,
|
|
agwStyle=AS_TIMEOUT | AS_CENTER_ON_SCREEN,
|
|
shadowcolour=wx.NullColour):
|
|
"""
|
|
Default class constructor.
|
|
|
|
:param `parent`: parent window;
|
|
:param integer `id`: window identifier. A value of -1 indicates a default value;
|
|
:param `pos`: the control position. A value of (-1, -1) indicates a default position,
|
|
chosen by either the windowing system or wxPython, depending on platform;
|
|
:param `size`: the control size. A value of (-1, -1) indicates a default size,
|
|
chosen by either the windowing system or wxPython, depending on platform;
|
|
:param integer `style`: the underlying :class:`Frame` style;
|
|
:param `bitmap`: this must be a valid bitmap, that you may construct using
|
|
whatever image file format supported by wxPython. If the file you load
|
|
already supports mask/transparency (like png), the transparent areas
|
|
will not be drawn on screen, and the :class:`AdvancedSplash` frame will have
|
|
the shape defined only by *non-transparent* pixels.
|
|
If you use other file formats that does not supports transparency, you
|
|
can obtain the same effect as above by masking a specific colour in
|
|
your :class:`Bitmap`.
|
|
:param integer `timeout`: if you construct :class:`AdvancedSplash` using the style ``AS_TIMEOUT``,
|
|
:class:`AdvancedSplash` will be destroyed after `timeout` milliseconds;
|
|
:param integer `agwStyle`: this value specifies the :class:`AdvancedSplash` styles:
|
|
|
|
======================= =========== ==================================================
|
|
Window Styles Hex Value Description
|
|
======================= =========== ==================================================
|
|
``AS_TIMEOUT`` 0x1 :class:`AdvancedSplash` will be destroyed after `timeout` milliseconds.
|
|
``AS_NOTIMEOUT`` 0x2 :class:`AdvancedSplash` can be destroyed by clicking on it, pressing a key or by explicitly call the `Close()` method.
|
|
``AS_CENTER_ON_SCREEN`` 0x4 :class:`AdvancedSplash` will be centered on screen.
|
|
``AS_CENTER_ON_PARENT`` 0x8 :class:`AdvancedSplash` will be centered on parent.
|
|
``AS_NO_CENTER`` 0x10 :class:`AdvancedSplash` will not be centered.
|
|
``AS_SHADOW_BITMAP`` 0x20 If the bitmap you pass as input has no transparency, you can choose one colour that will be masked in your bitmap. the final shape of :class:`AdvancedSplash` will be defined only by non-transparent (non-masked) pixels.
|
|
======================= =========== ==================================================
|
|
|
|
:param `shadowcolour`: if you construct :class:`AdvancedSplash` using the style
|
|
``AS_SHADOW_BITMAP``, here you can specify the colour that will be masked on
|
|
your input bitmap. This has to be a valid wxPython colour.
|
|
|
|
:type parent: :class:`Window`
|
|
:type pos: tuple or :class:`Point`
|
|
:type size: tuple or :class:`Size`
|
|
:type bitmap: :class:`Bitmap`
|
|
:type shadowcolour: :class:`Colour`
|
|
|
|
:raise: `Exception` in the following cases:
|
|
|
|
- The ``AS_TIMEOUT`` style is set but `timeout` is not a positive integer;
|
|
- The ``AS_SHADOW_BITMAP`` style is set but `shadowcolour` is not a valid wxPython colour;
|
|
- The :class:`AdvancedSplash` bitmap is an invalid :class:`Bitmap`.
|
|
|
|
"""
|
|
|
|
wx.Frame.__init__(self, parent, id, "", pos, size, style)
|
|
|
|
# Some Error Checking
|
|
if agwStyle & AS_TIMEOUT and timeout <= 0:
|
|
raise Exception('\nERROR: Style "AS_TIMEOUT" Used With Invalid "timeout" Parameter Value (' \
|
|
+ str(timeout) + ')')
|
|
|
|
if agwStyle & AS_SHADOW_BITMAP and not shadowcolour.IsOk():
|
|
raise Exception('\nERROR: Style "AS_SHADOW_BITMAP" Used With Invalid "shadowcolour" Parameter')
|
|
|
|
if not bitmap or not bitmap.IsOk():
|
|
raise Exception("\nERROR: Bitmap Passed To AdvancedSplash Is Invalid.")
|
|
|
|
if agwStyle & AS_SHADOW_BITMAP:
|
|
# Our Bitmap Is Masked Accordingly To User Input
|
|
self.bmp = self.ShadowBitmap(bitmap, shadowcolour)
|
|
else:
|
|
self.bmp = bitmap
|
|
|
|
self._agwStyle = agwStyle
|
|
|
|
# Setting Initial Properties
|
|
self.SetText()
|
|
self.SetTextFont()
|
|
self.SetTextPosition()
|
|
self.SetTextColour()
|
|
|
|
# Calculate The Shape Of AdvancedSplash Using The Input-Modified Bitmap
|
|
self.reg = wx.Region(self.bmp)
|
|
|
|
# Don't Know If It Works On Other Platforms!!
|
|
# Tested Only In Windows XP/2000
|
|
|
|
if wx.Platform == "__WXGTK__":
|
|
self.Bind(wx.EVT_WINDOW_CREATE, self.SetSplashShape)
|
|
else:
|
|
self.SetSplashShape()
|
|
|
|
w = self.bmp.GetWidth() + 1
|
|
h = self.bmp.GetHeight() + 1
|
|
|
|
# Set The AdvancedSplash Size To The Bitmap Size
|
|
self.SetClientSize((w, h))
|
|
|
|
if agwStyle & AS_CENTER_ON_SCREEN:
|
|
self.CenterOnScreen()
|
|
elif agwStyle & AS_CENTER_ON_PARENT:
|
|
self.CenterOnParent()
|
|
|
|
if agwStyle & AS_TIMEOUT:
|
|
# Starts The Timer. Once Expired, AdvancedSplash Is Destroyed
|
|
self._splashtimer = wx.Timer(self)
|
|
self.Bind(wx.EVT_TIMER, self.OnNotify)
|
|
self._splashtimer.Start(timeout)
|
|
|
|
# Catch Some Mouse Events, To Behave Like wx.SplashScreen
|
|
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
|
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
|
|
self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)
|
|
self.Bind(wx.EVT_CHAR, self.OnCharEvents)
|
|
|
|
self.Show()
|
|
if wx.Platform == "__WXMAC__":
|
|
wx.SafeYield(self, True)
|
|
|
|
|
|
def SetSplashShape(self, event=None):
|
|
"""
|
|
Sets :class:`AdvancedSplash` shape using the region created from the bitmap.
|
|
|
|
:param `event`: a :class:`WindowCreateEvent` event (GTK only, as GTK supports setting
|
|
the window shape only during window creation).
|
|
"""
|
|
|
|
self.SetShape(self.reg)
|
|
|
|
if event is not None:
|
|
event.Skip()
|
|
|
|
|
|
def ShadowBitmap(self, bmp, shadowcolour):
|
|
"""
|
|
Applies a mask on the bitmap accordingly to user input.
|
|
|
|
:param `bmp`: the bitmap to which we want to apply the mask colour `shadowcolour`;
|
|
:param `shadowcolour`: the mask colour for our bitmap.
|
|
:type bmp: :class:`Bitmap`
|
|
:type shadowcolour: :class:`Colour`
|
|
|
|
:return: A masked version of the input bitmap, an instance of :class:`Bitmap`.
|
|
"""
|
|
|
|
mask = wx.Mask(bmp, shadowcolour)
|
|
bmp.SetMask(mask)
|
|
|
|
return bmp
|
|
|
|
|
|
def OnPaint(self, event):
|
|
"""
|
|
Handles the ``wx.EVT_PAINT`` event for :class:`AdvancedSplash`.
|
|
|
|
:param `event`: a :class:`PaintEvent` to be processed.
|
|
"""
|
|
|
|
dc = wx.PaintDC(self)
|
|
|
|
# Here We Redraw The Bitmap Over The Frame
|
|
dc.DrawBitmap(self.bmp, 0, 0, True)
|
|
|
|
# We Draw The Text Anyway, Wheter It Is Empty ("") Or Not
|
|
textcolour = self.GetTextColour()
|
|
textfont = self.GetTextFont()
|
|
textpos = self.GetTextPosition()
|
|
text = self.GetText()
|
|
|
|
dc.SetFont(textfont[0])
|
|
dc.SetTextForeground(textcolour)
|
|
dc.DrawText(text, textpos[0], textpos[1])
|
|
|
|
|
|
def OnNotify(self, event):
|
|
"""
|
|
Handles the timer expiration, and calls the `Close()` method.
|
|
|
|
:param `event`: a :class:`wx.TimerEvent` to be processed.
|
|
"""
|
|
|
|
self.Close()
|
|
|
|
|
|
def OnMouseEvents(self, event):
|
|
"""
|
|
Handles the ``wx.EVT_MOUSE_EVENTS`` events for :class:`AdvancedSplash`.
|
|
|
|
:param `event`: a :class:`MouseEvent` to be processed.
|
|
|
|
:note: This reproduces the behavior of :class:`~adv.SplashScreen`.
|
|
"""
|
|
|
|
if event.LeftDown() or event.RightDown():
|
|
self.Close()
|
|
|
|
event.Skip()
|
|
|
|
|
|
def OnCharEvents(self, event):
|
|
"""
|
|
Handles the ``wx.EVT_CHAR`` event for :class:`AdvancedSplash`.
|
|
|
|
:param `event`: a :class:`KeyEvent` to be processed.
|
|
|
|
:note: This reproduces the behavior of :class:`~adv.SplashScreen`.
|
|
"""
|
|
|
|
self.Close()
|
|
|
|
|
|
def OnCloseWindow(self, event):
|
|
"""
|
|
Handles the ``wx.EVT_CLOSE`` event for :class:`AdvancedSplash`.
|
|
|
|
:param `event`: a :class:`CloseEvent` to be processed.
|
|
|
|
:note: This reproduces the behavior of :class:`~adv.SplashScreen`.
|
|
"""
|
|
|
|
if hasattr(self, "_splashtimer"):
|
|
self._splashtimer.Stop()
|
|
del self._splashtimer
|
|
|
|
self.Destroy()
|
|
|
|
|
|
def SetText(self, text=None):
|
|
"""
|
|
Sets the text to be displayed on :class:`AdvancedSplash`.
|
|
|
|
:param `text`: the text we want to display on top of the bitmap. If `text` is
|
|
set to ``None``, nothing will be drawn on top of the bitmap.
|
|
:type text: string or ``None``
|
|
"""
|
|
|
|
if text is None:
|
|
text = ""
|
|
|
|
self._text = text
|
|
|
|
self.Refresh()
|
|
self.Update()
|
|
|
|
|
|
def GetText(self):
|
|
"""
|
|
Returns the text displayed on :class:`AdvancedSplash`.
|
|
|
|
:return: A string representing the text drawn on top of the :class:`AdvancedSplash` bitmap.
|
|
"""
|
|
|
|
return self._text
|
|
|
|
|
|
def SetTextFont(self, font=None):
|
|
"""
|
|
Sets the font for the text in :class:`AdvancedSplash`.
|
|
|
|
:param `font`: the font to use while drawing the text on top of our bitmap. If `font`
|
|
is ``None``, a simple generic font is generated.
|
|
:type font: :class:`Font` or ``None``
|
|
"""
|
|
|
|
if font is None:
|
|
self._textfont = wx.Font(1, wx.SWISS, wx.NORMAL, wx.BOLD, False)
|
|
self._textsize = 10.0
|
|
self._textfont.SetPointSize(self._textsize)
|
|
else:
|
|
self._textfont = font
|
|
self._textsize = font.GetPointSize()
|
|
self._textfont.SetPointSize(self._textsize)
|
|
|
|
self.Refresh()
|
|
self.Update()
|
|
|
|
|
|
def GetTextFont(self):
|
|
"""
|
|
Gets the font for the text in :class:`AdvancedSplash`.
|
|
|
|
:return: An instance of :class:`Font` to draw the text and a :class:`Size` object containing
|
|
the text width an height, in pixels.
|
|
"""
|
|
|
|
return self._textfont, self._textsize
|
|
|
|
|
|
def SetTextColour(self, colour=None):
|
|
"""
|
|
Sets the colour for the text in :class:`AdvancedSplash`.
|
|
|
|
:param `colour`: the text colour to use while drawing the text on top of our
|
|
bitmap. If `colour` is ``None``, then ``wx.BLACK`` is used.
|
|
:type colour: :class:`Colour` or ``None``
|
|
"""
|
|
|
|
if colour is None:
|
|
colour = wx.BLACK
|
|
|
|
self._textcolour = colour
|
|
self.Refresh()
|
|
self.Update()
|
|
|
|
|
|
def GetTextColour(self):
|
|
"""
|
|
Gets the colour for the text in :class:`AdvancedSplash`.
|
|
|
|
:return: An instance of :class:`Colour`.
|
|
"""
|
|
|
|
return self._textcolour
|
|
|
|
|
|
def SetTextPosition(self, position=None):
|
|
"""
|
|
Sets the text position inside :class:`AdvancedSplash` frame.
|
|
|
|
:param `position`: the text position inside our bitmap. If `position` is ``None``,
|
|
the text will be placed at the top-left corner.
|
|
:type position: tuple or ``None``
|
|
"""
|
|
|
|
if position is None:
|
|
position = (0, 0)
|
|
|
|
self._textpos = position
|
|
self.Refresh()
|
|
self.Update()
|
|
|
|
|
|
def GetTextPosition(self):
|
|
"""
|
|
Returns the text position inside :class:`AdvancedSplash` frame.
|
|
|
|
:return: A tuple containing the text `x` and `y` position inside the :class:`AdvancedSplash` frame.
|
|
"""
|
|
|
|
return self._textpos
|
|
|
|
|
|
def GetSplashStyle(self):
|
|
"""
|
|
Returns a list of strings and a list of integers containing the styles.
|
|
|
|
:return: Two Python lists containing the style name and style values for :class:`AdvancedSplash`.
|
|
"""
|
|
|
|
stringstyle = []
|
|
integerstyle = []
|
|
|
|
if self._agwStyle & AS_TIMEOUT:
|
|
stringstyle.append("AS_TIMEOUT")
|
|
integerstyle.append(AS_TIMEOUT)
|
|
|
|
if self._agwStyle & AS_NOTIMEOUT:
|
|
stringstyle.append("AS_NOTIMEOUT")
|
|
integerstyle.append(AS_NOTIMEOUT)
|
|
|
|
if self._agwStyle & AS_CENTER_ON_SCREEN:
|
|
stringstyle.append("AS_CENTER_ON_SCREEN")
|
|
integerstyle.append(AS_CENTER_ON_SCREEN)
|
|
|
|
if self._agwStyle & AS_CENTER_ON_PARENT:
|
|
stringstyle.append("AS_CENTER_ON_PARENT")
|
|
integerstyle.append(AS_CENTER_ON_PARENT)
|
|
|
|
if self._agwStyle & AS_NO_CENTER:
|
|
stringstyle.append("AS_NO_CENTER")
|
|
integerstyle.append(AS_NO_CENTER)
|
|
|
|
if self._agwStyle & AS_SHADOW_BITMAP:
|
|
stringstyle.append("AS_SHADOW_BITMAP")
|
|
integerstyle.append(AS_SHADOW_BITMAP)
|
|
|
|
return stringstyle, integerstyle
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
import wx
|
|
|
|
app = wx.App(0)
|
|
|
|
bitmap = wx.Bitmap(100, 100)
|
|
splash = AdvancedSplash(None, bitmap=bitmap, timeout=5000)
|
|
|
|
app.MainLoop()
|